pgpool2.git / summary / log / commit / refs

commit    dabf4ac3beb0fa5fce5f76328ef235db7ca4de83
Author:   Tatsuo Ishii <ishii@sraoss.co.jp>
Date:     Fri Aug 17 08:23:14 2018 +0000

    Run pgindent.
    
    Fix and unify indentation by using PostgreSQL 11's pgindent command.


src/auth/auth-scram.c | 24 +- src/auth/md5.c | 112 +- src/auth/pool_auth.c | 936 +++-- src/auth/pool_hba.c | 454 +- src/auth/pool_passwd.c | 192 +- src/config/pool_config_variables.c | 3033 +++++++------- src/context/pool_process_context.c | 120 +- src/context/pool_query_context.c | 645 +-- src/context/pool_session_context.c | 434 +- src/include/auth/md5.h | 4 +- src/include/auth/pool_hba.h | 30 +- src/include/auth/pool_passwd.h | 31 +- src/include/auth/scram.h | 2 +- src/include/context/pool_process_context.h | 40 +- src/include/context/pool_query_context.h | 113 +- src/include/context/pool_session_context.h | 230 +- src/include/parser/explain.h | 12 +- src/include/parser/extensible.h | 8 +- src/include/parser/gramparse.h | 2 +- src/include/parser/lockoptions.h | 2 +- src/include/parser/makefuncs.h | 2 +- src/include/parser/nodes.h | 14 +- src/include/parser/parsenodes.h | 22 +- src/include/parser/pg_class.h | 49 +- src/include/parser/pool_parser.h | 23 +- src/include/parser/pool_string.h | 20 +- src/include/parser/primnodes.h | 17 +- src/include/parser/scansup.h | 2 +- src/include/parser/stringinfo.h | 6 +- src/include/pcp/libpcp_ext.h | 350 +- src/include/pcp/pcp.h | 40 +- src/include/pcp/pcp_stream.h | 35 +- src/include/pool.h | 594 +-- src/include/pool_config.h | 647 +-- src/include/pool_config_variables.h | 146 +- src/include/pool_type.h | 81 +- src/include/protocol/pool_proto_modules.h | 183 +- src/include/query_cache/pool_memqcache.h | 180 +- src/include/rewrite/pool_lobj.h | 6 +- src/include/rewrite/pool_timestamp.h | 6 +- src/include/utils/elog.h | 61 +- src/include/utils/fe_ports.h | 67 +- src/include/utils/getopt_long.h | 4 +- src/include/utils/json.h | 389 +- src/include/utils/json_writer.h | 61 +- src/include/utils/memdebug.h | 2 +- src/include/utils/pool_ip.h | 32 +- src/include/utils/pool_ipc.h | 4 +- src/include/utils/pool_path.h | 6 +- src/include/utils/pool_process_reporting.h | 34 +- src/include/utils/pool_relcache.h | 65 +- src/include/utils/pool_select_walker.h | 46 +- src/include/utils/pool_signal.h | 6 +- src/include/utils/pool_stream.h | 46 +- src/include/utils/regex_array.h | 47 +- src/include/utils/ssl_utils.h | 4 +- src/include/watchdog/watchdog.h | 86 +- src/include/watchdog/wd_ipc_commands.h | 40 +- src/include/watchdog/wd_ipc_defines.h | 39 +- src/include/watchdog/wd_json_data.h | 73 +- src/include/watchdog/wd_lifecheck.h | 30 +- src/include/watchdog/wd_utils.h | 29 +- src/libs/pcp/pcp.c | 940 +++-- src/main/health_check.c | 127 +- src/main/main.c | 342 +- src/main/pgpool_main.c | 1740 ++++---- src/main/pool_globals.c | 2 +- src/parser/copyfuncs.c | 6 +- src/parser/keywords.c | 2 +- src/parser/list.c | 12 +- src/parser/outfuncs.c | 1284 +++--- src/parser/parser.c | 17 +- src/parser/pool_string.c | 37 +- src/pcp_con/pcp_child.c | 139 +- src/pcp_con/pcp_worker.c | 636 +-- src/pcp_con/recovery.c | 182 +- src/protocol/CommandComplete.c | 133 +- src/protocol/child.c | 1080 ++--- src/protocol/pool_connection_pool.c | 353 +- src/protocol/pool_process_query.c | 2362 ++++++----- src/protocol/pool_proto2.c | 409 +- src/protocol/pool_proto_modules.c | 1531 +++---- src/query_cache/pool_memqcache.c | 1534 +++---- src/rewrite/pool_lobj.c | 86 +- src/rewrite/pool_timestamp.c | 443 +- src/sql/pgpool-recovery/pgpool-recovery.c | 132 +- src/sql/pgpool-regclass/pgpool-regclass.c | 45 +- src/sql/pgpool_adm/pgpool_adm.c | 226 +- src/sql/pgpool_adm/pgpool_adm.h | 10 +- src/streaming_replication/pool_worker_child.c | 177 +- src/test/C/test_extended.c | 58 +- src/test/parser/main.c | 26 +- src/test/parser/pool.h | 1 - .../tests/010.rewrite_timestamp/timestamp/main.c | 156 +- src/tools/fe_port.c | 54 +- src/tools/pcp/pcp_frontend_client.c | 361 +- src/tools/pgenc/pg_enc.c | 147 +- src/tools/pgmd5/pg_md5.c | 68 +- src/tools/pgproto/buffer.c | 32 +- src/tools/pgproto/buffer.h | 2 +- src/tools/pgproto/extended_query.c | 115 +- src/tools/pgproto/fe_memutils.h | 2 +- src/tools/pgproto/main.c | 164 +- src/tools/pgproto/pgproto.h | 17 +- src/tools/pgproto/read.c | 115 +- src/tools/pgproto/send.c | 31 +- src/utils/error/elog.c | 301 +- src/utils/getopt_long.c | 4 +- src/utils/json.c | 1813 ++++---- src/utils/json_writer.c | 155 +- src/utils/mmgr/mcxt.c | 6 +- src/utils/pcp/pcp_stream.c | 371 +- src/utils/pool_ip.c | 85 +- src/utils/pool_params.c | 96 +- src/utils/pool_path.c | 82 +- src/utils/pool_process_reporting.c | 697 ++-- src/utils/pool_relcache.c | 95 +- src/utils/pool_select_walker.c | 401 +- src/utils/pool_sema.c | 28 +- src/utils/pool_shmem.c | 36 +- src/utils/pool_signal.c | 29 +- src/utils/pool_ssl.c | 231 +- src/utils/pool_stream.c | 699 ++-- src/utils/ps_status.c | 33 +- src/utils/psprintf.c | 2 +- src/utils/regex_array.c | 68 +- src/utils/ssl_utils.c | 133 +- src/utils/statistics.c | 40 +- src/watchdog/test/stab.c | 73 +- src/watchdog/test/test.c | 36 +- src/watchdog/test/wd_child_t.c | 42 +- src/watchdog/test/wd_lifecheck_t.c | 38 +- src/watchdog/test/wd_packet_t.c | 38 +- src/watchdog/test/wd_ping_t.c | 11 +- src/watchdog/watchdog.c | 4337 +++++++++++--------- src/watchdog/wd_commands.c | 417 +- src/watchdog/wd_escalation.c | 64 +- src/watchdog/wd_heartbeat.c | 229 +- src/watchdog/wd_if.c | 226 +- src/watchdog/wd_json_data.c | 331 +- src/watchdog/wd_lifecheck.c | 483 ++- src/watchdog/wd_ping.c | 104 +- src/watchdog/wd_utils.c | 117 +- 143 files changed, 19871 insertions(+), 17434 deletions(-) diff --git a/src/auth/auth-scram.c b/src/auth/auth-scram.c index 3d755b664..d857eab01 100644 --- a/src/auth/auth-scram.c +++ b/src/auth/auth-scram.c @@ -211,8 +211,8 @@ static char *build_client_first_message(fe_scram_state *state); static char *build_client_final_message(fe_scram_state *state); static bool verify_server_signature(fe_scram_state *state); static void calculate_client_proof(fe_scram_state *state, - const char *client_final_message_without_proof, - uint8 *result); + const char *client_final_message_without_proof, + uint8 *result); static void read_client_first_message(scram_state *state, char *input); static void read_client_final_message(scram_state *state, char *input); @@ -1084,8 +1084,8 @@ read_client_final_message(scram_state *state, char *input) /* * Read channel-binding. We don't support channel binding, so it's * expected to always be "biws", which is "n,,", base64-encoded, or - * "eSws", which is "y,,". We also have to check whether the flag is - * the same one that the client originally sent. + * "eSws", which is "y,,". We also have to check whether the flag is the + * same one that the client originally sent. */ channel_binding = read_attr_value(&p, 'c'); if (!(strcmp(channel_binding, "biws") == 0 && state->cbind_flag == 'n') && @@ -1177,6 +1177,7 @@ static char * GetMockAuthenticationNonce(void) { static char mockNonce[MOCK_AUTH_NONCE_LEN] = "pgpool-II random nonce string"; + return mockNonce; } static char * @@ -1421,16 +1422,14 @@ build_client_final_message(fe_scram_state *state) calculate_client_proof(state, state->client_final_message_without_proof, client_proof); - ///// + /* /// */ appendStringInfoString(&buf, ",p="); /* - char *encoded_data = palloc(pg_b64_enc_len(SCRAM_KEY_LEN) + 1); - int len = encoded_data = pg_b64_encode((char *) client_proof, - SCRAM_KEY_LEN, - encoded_data); - encoded_data[len] = '\0'; - appendStringInfoString(&buf, encoded_data); + * char *encoded_data = palloc(pg_b64_enc_len(SCRAM_KEY_LEN) + 1); int len + * = encoded_data = pg_b64_encode((char *) client_proof, SCRAM_KEY_LEN, + * encoded_data); encoded_data[len] = '\0'; appendStringInfoString(&buf, + * encoded_data); */ enlargeStringInfo(&buf, pg_b64_enc_len(SCRAM_KEY_LEN)); @@ -1527,7 +1526,7 @@ read_server_final_message(fe_scram_state *state, char *input) char *err = read_attr_value(&input, 'e'); ereport(ERROR, - (errmsg("error received from server in SCRAM exchange: %s",err))); + (errmsg("error received from server in SCRAM exchange: %s", err))); return false; } @@ -1650,4 +1649,3 @@ pg_fe_scram_build_verifier(const char *password) return result; } - diff --git a/src/auth/md5.c b/src/auth/md5.c index 69942d2d3..9e598765b 100644 --- a/src/auth/md5.c +++ b/src/auth/md5.c @@ -84,17 +84,17 @@ typedef unsigned int uint32; /* == 32 bits */ const uint32 T[64] = { - 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, - 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, - 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, - 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, - 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, - 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; @@ -111,8 +111,7 @@ static uint8 * createPaddedCopyWithLength(uint8 *b, uint32 *l) { /* - * uint8 *b - message to be digested - * uint32 *l - length of b + * uint8 *b - message to be digested uint32 *l - length of b */ uint8 *ret; uint32 q; @@ -177,16 +176,16 @@ doTheRounds(uint32 X[16], uint32 state[4]) d = state[3]; /* round 1 */ - FF(a, b, c, d, X[ 0], S11, T[ 0]); - FF(d, a, b, c, X[ 1], S12, T[ 1]); - FF(c, d, a, b, X[ 2], S13, T[ 2]); - FF(b, c, d, a, X[ 3], S14, T[ 3]); - FF(a, b, c, d, X[ 4], S11, T[ 4]); - FF(d, a, b, c, X[ 5], S12, T[ 5]); - FF(c, d, a, b, X[ 6], S13, T[ 6]); - FF(b, c, d, a, X[ 7], S14, T[ 7]); - FF(a, b, c, d, X[ 8], S11, T[ 8]); - FF(d, a, b, c, X[ 9], S12, T[ 9]); + FF(a, b, c, d, X[0], S11, T[0]); + FF(d, a, b, c, X[1], S12, T[1]); + FF(c, d, a, b, X[2], S13, T[2]); + FF(b, c, d, a, X[3], S14, T[3]); + FF(a, b, c, d, X[4], S11, T[4]); + FF(d, a, b, c, X[5], S12, T[5]); + FF(c, d, a, b, X[6], S13, T[6]); + FF(b, c, d, a, X[7], S14, T[7]); + FF(a, b, c, d, X[8], S11, T[8]); + FF(d, a, b, c, X[9], S12, T[9]); FF(c, d, a, b, X[10], S13, T[10]); FF(b, c, d, a, X[11], S14, T[11]); FF(a, b, c, d, X[12], S11, T[12]); @@ -194,56 +193,56 @@ doTheRounds(uint32 X[16], uint32 state[4]) FF(c, d, a, b, X[14], S13, T[14]); FF(b, c, d, a, X[15], S14, T[15]); - GG(a, b, c, d, X[ 1], S21, T[16]); - GG(d, a, b, c, X[ 6], S22, T[17]); + GG(a, b, c, d, X[1], S21, T[16]); + GG(d, a, b, c, X[6], S22, T[17]); GG(c, d, a, b, X[11], S23, T[18]); - GG(b, c, d, a, X[ 0], S24, T[19]); - GG(a, b, c, d, X[ 5], S21, T[20]); + GG(b, c, d, a, X[0], S24, T[19]); + GG(a, b, c, d, X[5], S21, T[20]); GG(d, a, b, c, X[10], S22, T[21]); GG(c, d, a, b, X[15], S23, T[22]); - GG(b, c, d, a, X[ 4], S24, T[23]); - GG(a, b, c, d, X[ 9], S21, T[24]); + GG(b, c, d, a, X[4], S24, T[23]); + GG(a, b, c, d, X[9], S21, T[24]); GG(d, a, b, c, X[14], S22, T[25]); - GG(c, d, a, b, X[ 3], S23, T[26]); - GG(b, c, d, a, X[ 8], S24, T[27]); + GG(c, d, a, b, X[3], S23, T[26]); + GG(b, c, d, a, X[8], S24, T[27]); GG(a, b, c, d, X[13], S21, T[28]); - GG(d, a, b, c, X[ 2], S22, T[29]); - GG(c, d, a, b, X[ 7], S23, T[30]); + GG(d, a, b, c, X[2], S22, T[29]); + GG(c, d, a, b, X[7], S23, T[30]); GG(b, c, d, a, X[12], S24, T[31]); - HH(a, b, c, d, X[ 5], S31, T[32]); - HH(d, a, b, c, X[ 8], S32, T[33]); + HH(a, b, c, d, X[5], S31, T[32]); + HH(d, a, b, c, X[8], S32, T[33]); HH(c, d, a, b, X[11], S33, T[34]); HH(b, c, d, a, X[14], S34, T[35]); - HH(a, b, c, d, X[ 1], S31, T[36]); - HH(d, a, b, c, X[ 4], S32, T[37]); - HH(c, d, a, b, X[ 7], S33, T[38]); + HH(a, b, c, d, X[1], S31, T[36]); + HH(d, a, b, c, X[4], S32, T[37]); + HH(c, d, a, b, X[7], S33, T[38]); HH(b, c, d, a, X[10], S34, T[39]); HH(a, b, c, d, X[13], S31, T[40]); - HH(d, a, b, c, X[ 0], S32, T[41]); - HH(c, d, a, b, X[ 3], S33, T[42]); - HH(b, c, d, a, X[ 6], S34, T[43]); - HH(a, b, c, d, X[ 9], S31, T[44]); + HH(d, a, b, c, X[0], S32, T[41]); + HH(c, d, a, b, X[3], S33, T[42]); + HH(b, c, d, a, X[6], S34, T[43]); + HH(a, b, c, d, X[9], S31, T[44]); HH(d, a, b, c, X[12], S32, T[45]); HH(c, d, a, b, X[15], S33, T[46]); - HH(b, c, d, a, X[ 2], S34, T[47]); + HH(b, c, d, a, X[2], S34, T[47]); - II(a, b, c, d, X[ 0], S41, T[48]); - II(d, a, b, c, X[ 7], S42, T[49]); + II(a, b, c, d, X[0], S41, T[48]); + II(d, a, b, c, X[7], S42, T[49]); II(c, d, a, b, X[14], S43, T[50]); - II(b, c, d, a, X[ 5], S44, T[51]); + II(b, c, d, a, X[5], S44, T[51]); II(a, b, c, d, X[12], S41, T[52]); - II(d, a, b, c, X[ 3], S42, T[53]); + II(d, a, b, c, X[3], S42, T[53]); II(c, d, a, b, X[10], S43, T[54]); - II(b, c, d, a, X[ 1], S44, T[55]); - II(a, b, c, d, X[ 8], S41, T[56]); + II(b, c, d, a, X[1], S44, T[55]); + II(a, b, c, d, X[8], S41, T[56]); II(d, a, b, c, X[15], S42, T[57]); - II(c, d, a, b, X[ 6], S43, T[58]); + II(c, d, a, b, X[6], S43, T[58]); II(b, c, d, a, X[13], S44, T[59]); - II(a, b, c, d, X[ 4], S41, T[60]); + II(a, b, c, d, X[4], S41, T[60]); II(d, a, b, c, X[11], S42, T[61]); - II(c, d, a, b, X[ 2], S43, T[62]); - II(b, c, d, a, X[ 9], S44, T[63]); + II(c, d, a, b, X[2], S43, T[62]); + II(b, c, d, a, X[9], S44, T[63]); state[0] += a; state[1] += b; @@ -255,8 +254,7 @@ static int calculateDigestFromBuffer(uint8 *b, uint32 len, uint8 sum[16]) { /* - * uint8 *b - message to be digested - * uint32 len - length of b + * uint8 *b - message to be digested uint32 len - length of b * uint8 sum[16] - md5 digest calculated from b */ @@ -370,7 +368,7 @@ pool_md5_hash(const void *buff, size_t len, char *hexsum) if (!calculateDigestFromBuffer((uint8 *) buff, len, sum)) return 0; /* failed */ - bytesToHex((char *)sum, 16, hexsum); + bytesToHex((char *) sum, 16, hexsum); return 1; /* success */ } @@ -385,11 +383,11 @@ pool_md5_hash(const void *buff, size_t len, char *hexsum) */ int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, - char *buf) + char *buf) { - size_t passwd_len = strlen(passwd); - char *crypt_buf = malloc(passwd_len + salt_len); - int ret; + size_t passwd_len = strlen(passwd); + char *crypt_buf = malloc(passwd_len + salt_len); + int ret; if (!crypt_buf) return 0; /* failed */ diff --git a/src/auth/pool_auth.c b/src/auth/pool_auth.c index a405d7855..a786d9170 100644 --- a/src/auth/pool_auth.c +++ b/src/auth/pool_auth.c @@ -57,44 +57,46 @@ #define MAX_SASL_PAYLOAD_LEN 1024 -static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, int key, int protoMajor); -static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); -static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); -static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); -static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor, - char *storedPassword, PasswordType passwordType); -static int do_md5_single_backend(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); -static void send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt); -static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize); -static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password); -static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor); -static void sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen); +static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, int key, int protoMajor); +static int do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); +static void pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp); +static int do_crypt(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); +static int do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor, + char *storedPassword, PasswordType passwordType); +static int do_md5_single_backend(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); +static void send_md5auth_request(POOL_CONNECTION * frontend, int protoMajor, char *salt); +static int read_password_packet(POOL_CONNECTION * frontend, int protoMajor, char *password, int *pwdSize); +static int send_password_packet(POOL_CONNECTION * backend, int protoMajor, char *password); +static int send_auth_ok(POOL_CONNECTION * frontend, int protoMajor); +static void sendAuthRequest(POOL_CONNECTION * frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen); static long PostmasterRandom(void); -static int pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void *sasl_state, bool final); -static void* pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *username, char* storedPassword); -static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoMajor, int message_length, - char *username, char *storedPassword, PasswordType passwordType); -static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); -static void authenticate_frontend_cert(POOL_CONNECTION *frontend); -static void authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth); -static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend); -static bool get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, - char** password, PasswordType *passwordType); +static int pg_SASL_continue(POOL_CONNECTION * backend, char *payload, int payloadlen, void *sasl_state, bool final); +static void *pg_SASL_init(POOL_CONNECTION * backend, char *payload, int payloadlen, char *username, char *storedPassword); +static bool do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, int message_length, + char *username, char *storedPassword, PasswordType passwordType); +static void authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor); +static void authenticate_frontend_cert(POOL_CONNECTION * frontend); +static void authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth); +static void authenticate_frontend_clear_text(POOL_CONNECTION * frontend); +static bool get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, + char **password, PasswordType *passwordType); /* * Do authentication. Assuming the only caller is * make_persistent_db_connection(). */ -void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) +void +connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password) { - char kind; - int length; - int auth_kind; - char state; - char *p; - int pid, key; - bool keydata_done; + char kind; + int length; + int auth_kind; + char state; + char *p; + int pid, + key; + bool keydata_done; /* * read kind expecting 'R' packet (authentication response) @@ -104,15 +106,16 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) if (kind != 'R') { - char *msg; - int sts = 0; + char *msg; + int sts = 0; if (kind == 'E' || kind == 'N') { - sts = pool_extract_error_message(false, cp->con, cp->sp->major, false, &msg); + sts = pool_extract_error_message(false, cp->con, cp->sp->major, false, &msg); } - if (sts == 1) /* succeeded in extracting error/notice message */ + if (sts == 1) /* succeeded in extracting error/notice + * message */ { ereport(ERROR, (errmsg("failed to authenticate"), @@ -120,8 +123,8 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) pfree(msg); } ereport(ERROR, - (errmsg("failed to authenticate"), - errdetail("invalid authentication message response type, Expecting 'R' and received '%c'",kind))); + (errmsg("failed to authenticate"), + errdetail("invalid authentication message response type, Expecting 'R' and received '%c'", kind))); } /* read message length */ @@ -135,42 +138,42 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) "authentication method from response"); auth_kind = ntohl(auth_kind); ereport(DEBUG1, - (errmsg("authenticate kind = %d",auth_kind))); + (errmsg("authenticate kind = %d", auth_kind))); if (auth_kind == AUTH_REQ_OK) /* trust authentication? */ { cp->con->auth_kind = AUTH_REQ_OK; } - else if (auth_kind == AUTH_REQ_PASSWORD) /* clear text password? */ + else if (auth_kind == AUTH_REQ_PASSWORD) /* clear text password? */ { kind = send_password_packet(cp->con, PROTO_MAJOR_V3, password); if (kind != AUTH_REQ_OK) ereport(ERROR, - (errmsg("password authentication failed for user:%s",cp->sp->user), + (errmsg("password authentication failed for user:%s", cp->sp->user), errdetail("backend replied with invalid kind"))); cp->con->auth_kind = AUTH_REQ_OK; return; } - else if (auth_kind == AUTH_REQ_CRYPT) /* crypt password? */ + else if (auth_kind == AUTH_REQ_CRYPT) /* crypt password? */ { - char salt[3]; - char *crypt_password; + char salt[3]; + char *crypt_password; - pool_read_with_error(cp->con, &salt, 2,"crypt salt"); + pool_read_with_error(cp->con, &salt, 2, "crypt salt"); salt[2] = '\0'; crypt_password = crypt(password, salt); if (crypt_password == NULL) ereport(ERROR, - (errmsg("crypt authentication failed for user:%s",cp->sp->user), + (errmsg("crypt authentication failed for user:%s", cp->sp->user), errdetail("failed to encrypt the password"))); /* Send password packet to backend and receive auth response */ kind = send_password_packet(cp->con, PROTO_MAJOR_V3, crypt_password); if (kind != AUTH_REQ_OK) ereport(ERROR, - (errmsg("crypt authentication failed for user:%s",cp->sp->user), + (errmsg("crypt authentication failed for user:%s", cp->sp->user), errdetail("backend replied with invalid kind"))); cp->con->auth_kind = AUTH_REQ_OK; @@ -178,12 +181,13 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) } else if (auth_kind == AUTH_REQ_MD5) /* md5 password? */ { - char salt[4]; - char *buf, *buf1; + char salt[4]; + char *buf, + *buf1; - pool_read_with_error(cp->con, &salt, sizeof(salt),"authentication md5 salt"); + pool_read_with_error(cp->con, &salt, sizeof(salt), "authentication md5 salt"); - buf = palloc0(2 * (MD5_PASSWD_LEN + 4)); /* hash + "md5" + '\0' */ + buf = palloc0(2 * (MD5_PASSWD_LEN + 4)); /* hash + "md5" + '\0' */ /* build md5 password */ buf1 = buf + MD5_PASSWD_LEN + 4; @@ -196,7 +200,7 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) pfree(buf); if (kind != AUTH_REQ_OK) ereport(ERROR, - (errmsg("md5 authentication failed for user:%s",cp->sp->user), + (errmsg("md5 authentication failed for user:%s", cp->sp->user), errdetail("backend replied with invalid kind"))); cp->con->auth_kind = AUTH_REQ_OK; @@ -207,11 +211,11 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) if (do_SCRAM(NULL, cp->con, PROTO_MAJOR_V3, length, cp->sp->user, password, PASSWORD_TYPE_PLAINTEXT) == false) { ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("SCRAM authentication failed for user:%s",cp->sp->user))); + (errmsg("failed to authenticate with backend"), + errdetail("SCRAM authentication failed for user:%s", cp->sp->user))); } ereport(DEBUG1, - (errmsg("SCRAM authentication successful for user:%s",cp->sp->user))); + (errmsg("SCRAM authentication successful for user:%s", cp->sp->user))); } else @@ -222,8 +226,8 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) } /* - * Read backend key data and wait until Ready for query arriving or - * error happens. + * Read backend key data and wait until Ready for query arriving or error + * happens. */ keydata_done = false; @@ -235,23 +239,23 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) switch (kind) { - case 'K': /* backend key data */ + case 'K': /* backend key data */ keydata_done = true; ereport(DEBUG1, (errmsg("authenticate backend: key data received"))); /* read message length */ - pool_read_with_error(cp->con, &length, sizeof(length),"message length for authentication kind 'K'"); + pool_read_with_error(cp->con, &length, sizeof(length), "message length for authentication kind 'K'"); if (ntohl(length) != 12) { ereport(ERROR, (errmsg("failed to authenticate"), errdetail("invalid backend key data length. received %d bytes when expecting 12 bytes" - , ntohl(length)))); + ,ntohl(length)))); } /* read pid */ - pool_read_with_error(cp->con, &pid, sizeof(pid),"pid for authentication kind 'K'"); + pool_read_with_error(cp->con, &pid, sizeof(pid), "pid for authentication kind 'K'"); cp->pid = pid; /* read key */ @@ -260,7 +264,7 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) cp->key = key; break; - case 'Z': /* Ready for query */ + case 'Z': /* Ready for query */ /* read message length */ pool_read_with_error(cp->con, &length, sizeof(length), "message length for authentication kind 'Z'"); @@ -284,9 +288,9 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) return; break; - case 'S': /* parameter status */ - case 'N': /* notice response */ - case 'E': /* error response */ + case 'S': /* parameter status */ + case 'N': /* notice response */ + case 'E': /* error response */ /* Just throw away data */ pool_read_with_error(cp->con, &length, sizeof(length), "backend message length"); @@ -305,7 +309,7 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) default: ereport(ERROR, (errmsg("failed to authenticate"), - errdetail("unknown authentication message response received '%c'",kind))); + errdetail("unknown authentication message response received '%c'", kind))); break; } } @@ -318,47 +322,49 @@ void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password) * authentication against backend. if success return 0 otherwise non * 0. */ -int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) +int +pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) { signed char kind; - int pid; - int key; - int protoMajor; - int length; - int authkind; - int i; - int message_length = 0; + int pid; + int key; + int protoMajor; + int length; + int authkind; + int i; + int message_length = 0; StartupPacket *sp; - + protoMajor = MASTER_CONNECTION(cp)->sp->major; kind = pool_read_kind(cp); if (kind < 0) ereport(ERROR, - (errmsg("invalid authentication packet from backend"), - errdetail("failed to get response kind"))); + (errmsg("invalid authentication packet from backend"), + errdetail("failed to get response kind"))); /* error response? */ if (kind == 'E') { - /* we assume error response at this stage is likely version - * protocol mismatch (v3 frontend vs. v2 backend). So we throw - * a V2 protocol error response in the hope that v3 frontend - * will negotiate again using v2 protocol. + /* + * we assume error response at this stage is likely version protocol + * mismatch (v3 frontend vs. v2 backend). So we throw a V2 protocol + * error response in the hope that v3 frontend will negotiate again + * using v2 protocol. */ ErrorResponse(frontend, cp); ereport(ERROR, - (errmsg("backend authentication failed"), - errdetail("backend response with kind \'E\' when expecting \'R\'"), - errhint("This issue can be caused by version mismatch (current version %d)", protoMajor))); + (errmsg("backend authentication failed"), + errdetail("backend response with kind \'E\' when expecting \'R\'"), + errhint("This issue can be caused by version mismatch (current version %d)", protoMajor))); } else if (kind != 'R') ereport(ERROR, - (errmsg("backend authentication failed"), - errdetail("backend response with kind \'%c\' when expecting \'R\'",kind))); + (errmsg("backend authentication failed"), + errdetail("backend response with kind \'%c\' when expecting \'R\'", kind))); /* * message length (v3 only) @@ -368,9 +374,9 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) message_length = pool_read_message_length(cp); if (message_length <= 0) ereport(ERROR, - (errmsg("invalid authentication packet from backend"), - errdetail("failed to get the authentication packet length"), - errhint("This is likely caused by the inconsistency of auth method among DB nodes. \ + (errmsg("invalid authentication packet from backend"), + errdetail("failed to get the authentication packet length"), + errhint("This is likely caused by the inconsistency of auth method among DB nodes. \ Please check the previous error messages (hint: length field) \ from pool_read_message_length and recheck the pg_hba.conf settings."))); } @@ -395,18 +401,18 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) authkind = pool_read_int(cp); if (authkind < 0) ereport(ERROR, - (errmsg("invalid authentication packet from backend"), - errdetail("failed to get auth kind"))); + (errmsg("invalid authentication packet from backend"), + errdetail("failed to get auth kind"))); authkind = ntohl(authkind); ereport(DEBUG1, - (errmsg("authentication backend"), + (errmsg("authentication backend"), errdetail("auth kind:%d", authkind))); /* trust? */ if (authkind == AUTH_REQ_OK) { - int msglen; + int msglen; pool_write(frontend, "R", 1); @@ -424,13 +430,13 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) /* clear text password authentication? */ else if (authkind == AUTH_REQ_PASSWORD) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; ereport(DEBUG1, - (errmsg("authentication backend"), + (errmsg("authentication backend"), errdetail("trying clear text password authentication"))); authkind = do_clear_text_password(CONNECTION(cp, i), frontend, 0, protoMajor); @@ -438,12 +444,12 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) if (authkind < 0) { ereport(DEBUG1, - (errmsg("authentication backend"), + (errmsg("authentication backend"), errdetail("clear text password failed in slot %d", i))); pool_send_auth_fail(frontend, cp); ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("do_clear_text_password failed in slot %d", i))); + (errmsg("failed to authenticate with backend"), + errdetail("do_clear_text_password failed in slot %d", i))); } } } @@ -451,13 +457,13 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) /* crypt authentication? */ else if (authkind == AUTH_REQ_CRYPT) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; ereport(DEBUG1, - (errmsg("authentication backend"), + (errmsg("authentication backend"), errdetail("trying crypt authentication"))); authkind = do_crypt(CONNECTION(cp, i), frontend, 0, protoMajor); @@ -466,8 +472,8 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { pool_send_auth_fail(frontend, cp); ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("do_crypt_text_password failed in slot %d", i))); + (errmsg("failed to authenticate with backend"), + errdetail("do_crypt_text_password failed in slot %d", i))); } } } @@ -475,27 +481,27 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) /* md5 authentication? */ else if (authkind == AUTH_REQ_MD5) { - char *password; + char *password; PasswordType passwordType; /* * check if we can use md5 authentication. */ - if (NUM_BACKENDS > 1) + if (NUM_BACKENDS > 1) { if (get_auth_password(MASTER(cp), frontend, 0, &password, &passwordType) == false) { /* - * We do not have any passeord, - * we can still get the password from client using plain text authentication - * if it is allowed by user + * We do not have any passeord, we can still get the password + * from client using plain text authentication if it is + * allowed by user */ if (frontend->pool_hba == NULL && pool_config->allow_clear_text_frontend_auth) { ereport(LOG, - (errmsg("using clear text authentication with frontend"), - errdetail("backend will still use md5 auth"), + (errmsg("using clear text authentication with frontend"), + errdetail("backend will still use md5 auth"), errhint("you can disable this behavior by setting allow_clear_text_frontend_auth to off"))); authenticate_frontend_clear_text(frontend); /* now check again if we have a password now */ @@ -503,7 +509,7 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) &password, &passwordType) == false) { ereport(ERROR, - (errmsg("failed to authenticate with backend using md5"), + (errmsg("failed to authenticate with backend using md5"), errdetail("unable to get the password"))); } } @@ -513,18 +519,18 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) && passwordType != PASSWORD_TYPE_AES) { ereport(ERROR, - (errmsg("failed to authenticate with backend using md5"), + (errmsg("failed to authenticate with backend using md5"), errdetail("valid password not found"))); } } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; ereport(DEBUG1, - (errmsg("authentication backend: %d",i), + (errmsg("authentication backend: %d", i), errdetail("trying md5 authentication"))); authkind = do_md5(CONNECTION(cp, i), frontend, 0, protoMajor, password, passwordType); @@ -533,8 +539,8 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { pool_send_auth_fail(frontend, cp); ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("MD5 authentication failed in slot [%d].",i))); + (errmsg("failed to authenticate with backend"), + errdetail("MD5 authentication failed in slot [%d].", i))); } } } @@ -542,21 +548,20 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) /* SCRAM authentication? */ else if (authkind == AUTH_REQ_SASL) { - char *password; + char *password; PasswordType passwordType = PASSWORD_TYPE_UNKNOWN; if (get_auth_password(MASTER(cp), frontend, 0, &password, &passwordType) == false) { /* - * We do not have any password, - * we can still get the password from client using plain text authentication - * if it is allowed by user + * We do not have any password, we can still get the password from + * client using plain text authentication if it is allowed by user */ if (frontend->pool_hba == NULL && pool_config->allow_clear_text_frontend_auth) { ereport(LOG, - (errmsg("using clear text authentication with frontend"), + (errmsg("using clear text authentication with frontend"), errdetail("backend will still use SCRAM auth"), errhint("you can disable this behavior by setting allow_clear_text_frontend_auth to off"))); authenticate_frontend_clear_text(frontend); @@ -570,9 +575,9 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) } } } + /* - * if we have encrypted password, - * Decrypt it before going any further + * if we have encrypted password, Decrypt it before going any further */ if (passwordType == PASSWORD_TYPE_AES) { @@ -594,13 +599,13 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) errdetail("valid password not found"))); } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; ereport(DEBUG1, - (errmsg("authentication backend %d",i), + (errmsg("authentication backend %d", i), errdetail("trying SCRAM authentication"))); if (do_SCRAM(frontend, CONNECTION(cp, i), protoMajor, message_length, frontend->username, password, passwordType) == false) @@ -608,10 +613,10 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) pool_send_auth_fail(frontend, cp); ereport(ERROR, (errmsg("failed to authenticate with backend"), - errdetail("SCRAM authentication failed in slot [%d].",i))); + errdetail("SCRAM authentication failed in slot [%d].", i))); } ereport(DEBUG1, - (errmsg("SCRAM authentication successful for backend %d",i))); + (errmsg("SCRAM authentication successful for backend %d", i))); } @@ -622,29 +627,29 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) else { ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("unsupported auth kind received from backend: authkind:%d", authkind))); + (errmsg("failed to authenticate with backend"), + errdetail("unsupported auth kind received from backend: authkind:%d", authkind))); } if (authkind != 0) ereport(ERROR, - (errmsg("failed to authenticate with backend"), - errdetail("invalid auth kind received from backend: authkind:%d", authkind))); + (errmsg("failed to authenticate with backend"), + errdetail("invalid auth kind received from backend: authkind:%d", authkind))); /* - * authentication ok. now read pid and secret key from the - * backend + * authentication ok. now read pid and secret key from the backend */ for (;;) { - char *message = NULL; + char *message = NULL; + kind = pool_read_kind(cp); if (kind < 0) { ereport(ERROR, - (errmsg("authentication failed from backend"), - errdetail("failed to read kind before BackendKeyData"))); + (errmsg("authentication failed from backend"), + errdetail("failed to read kind before BackendKeyData"))); } else if (kind == 'K') break; @@ -664,15 +669,15 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) if (pool_extract_error_message(false, MASTER(cp), protoMajor, true, &message) == 1) { ereport(NOTICE, - (errmsg("notice from backend"), - errdetail("BACKEND NOTICE: \"%s\"",message))); + (errmsg("notice from backend"), + errdetail("BACKEND NOTICE: \"%s\"", message))); pfree(message); } /* process notice message */ if (SimpleForwardToFrontend(kind, frontend, cp)) ereport(ERROR, - (errmsg("authentication failed"), - errdetail("failed to forward message to frontend"))); + (errmsg("authentication failed"), + errdetail("failed to forward message to frontend"))); pool_flush(frontend); break; @@ -683,7 +688,7 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) { ereport(LOG, (errmsg("backend throws an error message"), - errdetail("%s",message))); + errdetail("%s", message))); } SimpleForwardToFrontend(kind, frontend, cp); @@ -691,8 +696,8 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) pool_flush(frontend); ereport(ERROR, - (errmsg("authentication failed, backend node replied with an error"), - errdetail("SERVER ERROR:\"%s\"",message?message:"could not extract backend message"))); + (errmsg("authentication failed, backend node replied with an error"), + errdetail("SERVER ERROR:\"%s\"", message ? message : "could not extract backend message"))); if (message) pfree(message); @@ -700,8 +705,8 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) default: ereport(ERROR, - (errmsg("authentication failed"), - errdetail("unknown response \"%c\" before processing BackendKeyData",kind))); + (errmsg("authentication failed"), + errdetail("unknown response \"%c\" before processing BackendKeyData", kind))); break; } } @@ -718,11 +723,11 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) /* process error message */ case 'E': ErrorResponse(frontend, cp); - /* fallthrough*/ + /* fallthrough */ default: ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid response \"%c\" before processing BackendKeyData",kind))); + (errmsg("authentication failed"), + errdetail("invalid response \"%c\" before processing BackendKeyData", kind))); break; } } @@ -736,8 +741,8 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) if ((length = pool_read_message_length(cp)) != 12) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid messages length(%d) for BackendKeyData", length))); + (errmsg("authentication failed"), + errdetail("invalid messages length(%d) for BackendKeyData", length))); } } @@ -747,7 +752,7 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) sp = MASTER_CONNECTION(cp)->sp; pid = -1; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -755,11 +760,11 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) if (pool_read(CONNECTION(cp, i), &pid, sizeof(pid)) < 0) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("failed to read pid in slot %d", i))); + (errmsg("authentication failed"), + errdetail("failed to read pid in slot %d", i))); } ereport(DEBUG1, - (errmsg("authentication backend"), + (errmsg("authentication backend"), errdetail("cp->info[i]:%p pid:%u", &cp->info[i], ntohl(pid)))); CONNECTION_SLOT(cp, i)->pid = cp->info[i].pid = pid; @@ -768,8 +773,8 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) if (pool_read(CONNECTION(cp, i), &key, sizeof(key)) < 0) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("failed to read key in slot %d", i))); + (errmsg("authentication failed"), + errdetail("failed to read key in slot %d", i))); } CONNECTION_SLOT(cp, i)->key = cp->info[i].key = key; @@ -786,31 +791,33 @@ int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) if (pid == -1) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("pool_do_auth: all backends are down"))); + (errmsg("authentication failed"), + errdetail("pool_do_auth: all backends are down"))); } - if(pool_send_backend_key_data(frontend, pid, key, protoMajor)) + if (pool_send_backend_key_data(frontend, pid, key, protoMajor)) ereport(ERROR, - (errmsg("authentication failed"), - errdetail("failed to send backend data to frontend"))); + (errmsg("authentication failed"), + errdetail("failed to send backend data to frontend"))); return 0; } /* * do re-authentication for reused connection. if success return 0 otherwise throws ereport. */ -int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) +int +pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) { - int protoMajor; - int msglen; + int protoMajor; + int msglen; protoMajor = MAJOR(cp); + /* * if hba is enabled we would already have passed authentication */ if (!frontend->frontend_authenticated) { - switch(MASTER(cp)->auth_kind) + switch (MASTER(cp)->auth_kind) { case AUTH_REQ_OK: /* trust */ @@ -836,56 +843,57 @@ int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) break; default: ereport(ERROR, - (errmsg("authentication failed"), - errdetail("unknown authentication request code %d",MASTER(cp)->auth_kind))); + (errmsg("authentication failed"), + errdetail("unknown authentication request code %d", MASTER(cp)->auth_kind))); } } - pool_write(frontend, "R", 1); + pool_write(frontend, "R", 1); - if (protoMajor == PROTO_MAJOR_V3) - { - msglen = htonl(8); - pool_write(frontend, &msglen, sizeof(msglen)); - } + if (protoMajor == PROTO_MAJOR_V3) + { + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); + } - msglen = htonl(0); - pool_write_and_flush(frontend, &msglen, sizeof(msglen)); + msglen = htonl(0); + pool_write_and_flush(frontend, &msglen, sizeof(msglen)); pool_send_backend_key_data(frontend, MASTER_CONNECTION(cp)->pid, MASTER_CONNECTION(cp)->key, protoMajor); - return 0; + return 0; } /* * send authentication failure message text to frontend */ -static void pool_send_auth_fail(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) +static void +pool_send_auth_fail(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp) { - int messagelen; - char *errmessage; - int protoMajor; + int messagelen; + char *errmessage; + int protoMajor; - bool send_error_to_frontend = true; + bool send_error_to_frontend = true; protoMajor = MAJOR(cp); messagelen = strlen(MASTER_CONNECTION(cp)->sp->user) + 100; - errmessage = (char *)palloc(messagelen+1); + errmessage = (char *) palloc(messagelen + 1); snprintf(errmessage, messagelen, "password authentication failed for user \"%s\"", - MASTER_CONNECTION(cp)->sp->user); + MASTER_CONNECTION(cp)->sp->user); if (send_error_to_frontend) - pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage, - "", "", __FILE__, __LINE__); + pool_send_fatal_message(frontend, protoMajor, "XX000", errmessage, + "", "", __FILE__, __LINE__); pfree(errmessage); -} +} /* * Send backend key data to frontend. if success return 0 otherwise non 0. */ -static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid, int key, int protoMajor) +static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION * frontend, int pid, int key, int protoMajor) { - char kind; - int len; + char kind; + int len; /* Send backend key data */ kind = 'K'; @@ -896,7 +904,7 @@ static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid pool_write(frontend, &len, sizeof(len)); } ereport(DEBUG1, - (errmsg("sending backend key data"), + (errmsg("sending backend key data"), errdetail("send pid %d to frontend", ntohl(pid)))); pool_write(frontend, &pid, sizeof(pid)); @@ -905,13 +913,14 @@ static POOL_STATUS pool_send_backend_key_data(POOL_CONNECTION *frontend, int pid return 0; } -static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend) +static void +authenticate_frontend_clear_text(POOL_CONNECTION * frontend) { - static int size; - char password[MAX_PASSWORD_SIZE]; - char userPassword[MAX_PASSWORD_SIZE]; - char *storedPassword = NULL; - char *userPwd = NULL; + static int size; + char password[MAX_PASSWORD_SIZE]; + char userPassword[MAX_PASSWORD_SIZE]; + char *storedPassword = NULL; + char *userPwd = NULL; sendAuthRequest(frontend, frontend->protoVersion, AUTH_REQ_PASSWORD, NULL, 0); @@ -922,14 +931,14 @@ static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend) frontend->auth_kind = AUTH_REQ_PASSWORD; frontend->pwd_size = size; memcpy(frontend->password, password, frontend->pwd_size); - frontend->password[size] = 0; /* Null terminate the password string */ + frontend->password[size] = 0; /* Null terminate the password string */ frontend->passwordType = PASSWORD_TYPE_PLAINTEXT; if (!frontend->passwordMapping) { /* - * if the password is not present in pool_passwd - * just bail out from here + * if the password is not present in pool_passwd just bail out from + * here */ return; } @@ -947,25 +956,24 @@ static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend) frontend->username, strlen(frontend->username), userPassword); userPwd = userPassword; - size = strlen (userPwd); + size = strlen(userPwd); } else if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_AES) { /* - * decrypt the stored AES password - * for comparing it + * decrypt the stored AES password for comparing it */ storedPassword = get_decrypted_password(storedPassword); if (storedPassword == NULL) ereport(ERROR, - (errmsg("clear text authentication failed"), + (errmsg("clear text authentication failed"), errdetail("unable to decrypt password from pool_passwd"), errhint("verify the valid pool_key exists"))); } else if (frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_PLAINTEXT) { ereport(ERROR, - (errmsg("clear text authentication failed"), + (errmsg("clear text authentication failed"), errdetail("password type stored in pool_passwd can't be used for clear text authentication"))); } @@ -973,7 +981,7 @@ static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend) { /* Password does not match */ ereport(ERROR, - (errmsg("clear text authentication failed"), + (errmsg("clear text authentication failed"), errdetail("password does not match"))); } ereport(LOG, @@ -988,11 +996,12 @@ static void authenticate_frontend_clear_text(POOL_CONNECTION *frontend) /* * perform clear text password authentication */ -static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +static int +do_clear_text_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) { - static int size; - char *pwd = NULL; - int kind; + static int size; + char *pwd = NULL; + int kind; if (reauth && frontend->frontend_authenticated) { @@ -1011,18 +1020,17 @@ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *fro if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_PLAINTEXT) { pwd = frontend->passwordMapping->pgpoolUser.password; - size = pwd? strlen(pwd): 0; + size = pwd ? strlen(pwd) : 0; } else if (frontend->passwordMapping->pgpoolUser.passwordType == PASSWORD_TYPE_AES) { /* - * decrypt the stored AES password - * for comparing it + * decrypt the stored AES password for comparing it */ pwd = get_decrypted_password(frontend->passwordMapping->pgpoolUser.password); if (pwd == NULL) ereport(ERROR, - (errmsg("clear text password authentication failed"), + (errmsg("clear text password authentication failed"), errdetail("unable to decrypt password from pool_passwd"), errhint("verify the valid pool_key exists"))); size = strlen(pwd); @@ -1032,7 +1040,7 @@ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *fro { /* If we still do not have a password. we can't proceed */ ereport(ERROR, - (errmsg("clear text password authentication failed"), + (errmsg("clear text password authentication failed"), errdetail("unable to get the password"))); return 0; } @@ -1041,14 +1049,14 @@ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *fro if (reauth) { if (size != backend->pwd_size) - ereport(ERROR, - (errmsg("clear text password authentication failed"), - errdetail("password size does not match"))); + ereport(ERROR, + (errmsg("clear text password authentication failed"), + errdetail("password size does not match"))); if (memcmp(pwd, backend->password, backend->pwd_size) != 0) - ereport(ERROR, - (errmsg("clear text password authentication failed"), - errdetail("password does not match"))); + ereport(ERROR, + (errmsg("clear text password authentication failed"), + errdetail("password does not match"))); return 0; } @@ -1074,14 +1082,15 @@ static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *fro /* * perform crypt authentication */ -static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +static int +do_crypt(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) { - char salt[2]; - static int size; + char salt[2]; + static int size; static char password[MAX_PASSWORD_SIZE]; - char response; - int kind; - int len; + char response; + int kind; + int len; if (!reauth) { @@ -1103,8 +1112,9 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea pool_write(frontend, &len, sizeof(len)); } kind = htonl(4); /* crypt authentication */ - pool_write(frontend, &kind, sizeof(kind)); /* indicating crypt authentication */ - pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */ + pool_write(frontend, &kind, sizeof(kind)); /* indicating crypt + * authentication */ + pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */ /* read password packet */ if (protoMajor == PROTO_MAJOR_V2) @@ -1113,23 +1123,23 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea } else { - char k; + char k; pool_read(frontend, &k, sizeof(k)); if (k != 'p') { - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("invalid password packet. Packet does not starts with \"p\""))); + ereport(ERROR, + (errmsg("crypt authentication failed"), + errdetail("invalid password packet. Packet does not starts with \"p\""))); } pool_read(frontend, &size, sizeof(size)); } if ((ntohl(size) - 4) > sizeof(password)) { - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("password is too long, password size is %d", ntohl(size) - 4))); + ereport(ERROR, + (errmsg("crypt authentication failed"), + errdetail("password is too long, password size is %d", ntohl(size) - 4))); } pool_read(frontend, password, ntohl(size) - 4); @@ -1139,19 +1149,19 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea if (reauth) { ereport(DEBUG1, - (errmsg("performing crypt authentication"), + (errmsg("performing crypt authentication"), errdetail("size: %d saved_size: %d", (ntohl(size) - 4), backend->pwd_size))); if ((ntohl(size) - 4) != backend->pwd_size) - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("password size does not match"))); + ereport(ERROR, + (errmsg("crypt authentication failed"), + errdetail("password size does not match"))); if (memcmp(password, backend->password, backend->pwd_size) != 0) - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("password does not match"))); + ereport(ERROR, + (errmsg("crypt authentication failed"), + errdetail("password does not match"))); return 0; } @@ -1160,26 +1170,27 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea if (protoMajor == PROTO_MAJOR_V3) pool_write(backend, "p", 1); pool_write(backend, &size, sizeof(size)); - pool_write_and_flush(backend, password, ntohl(size) -4); + pool_write_and_flush(backend, password, ntohl(size) - 4); pool_read(backend, &response, sizeof(response)); if (response != 'R') { - if(response == 'E') /* Backend has thrown an error instead */ + if (response == 'E') /* Backend has thrown an error instead */ { - char* message = NULL; + char *message = NULL; + if (pool_extract_error_message(false, backend, protoMajor, false, &message) == 1) { ereport(ERROR, (errmsg("crypt authentication failed"), - errdetail("%s",message?message:"backend throws authentication error"))); + errdetail("%s", message ? message : "backend throws authentication error"))); } if (message) pfree(message); } - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("invalid packet from backend. backend does not return R while processing clear text password authentication"))); + ereport(ERROR, + (errmsg("crypt authentication failed"), + errdetail("invalid packet from backend. backend does not return R while processing clear text password authentication"))); } if (protoMajor == PROTO_MAJOR_V3) @@ -1187,9 +1198,9 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea pool_read(backend, &len, sizeof(len)); if (ntohl(len) != 8) - ereport(ERROR, - (errmsg("crypt authentication failed"), - errdetail("invalid packet from backend. incorrect authentication packet size (%d)", ntohl(len)))); + ereport(ERROR, + (errmsg("crypt authentication failed"), + errdetail("invalid packet from backend. incorrect authentication packet size (%d)", ntohl(len)))); } /* expect to read "Authentication OK" response. kind should be 0... */ @@ -1198,7 +1209,7 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea /* if authenticated, save info */ if (!reauth && kind == 0) { - int msglen; + int msglen; pool_write(frontend, "R", 1); @@ -1224,7 +1235,7 @@ static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int rea * password in the pool_passwd file. */ static void -authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth) +authenticate_frontend_SCRAM(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth) { void *scram_opaq; char *output = NULL; @@ -1233,11 +1244,11 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int inputlen; int result; bool initial; - char *logdetail = NULL; - char *shadow_pass; + char *logdetail = NULL; + char *shadow_pass; PasswordType storedPasswordType = PASSWORD_TYPE_UNKNOWN; - char *storedPassword = NULL; + char *storedPassword = NULL; if (!frontend->passwordMapping) frontend->passwordMapping = pool_get_user_credentials(frontend->username); @@ -1253,9 +1264,9 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, else { ereport(FATAL, - (return_code(2), + (return_code(2), errmsg("SCRAM authentication failed"), - errdetail("pool_passwd file does not contain an entry for \"%s\"",frontend->username))); + errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username))); } } else @@ -1267,8 +1278,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, if (storedPasswordType == PASSWORD_TYPE_AES) { /* - * decrypt the stored AES password - * for comparing it + * decrypt the stored AES password for comparing it */ storedPassword = get_decrypted_password(storedPassword); if (storedPassword == NULL) @@ -1283,14 +1293,14 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, if (storedPasswordType != PASSWORD_TYPE_PLAINTEXT) { ereport(ERROR, - (errmsg("SCRAM authentication failed"), - errdetail("username \"%s\" has invalid password type",frontend->username))); + (errmsg("SCRAM authentication failed"), + errdetail("username \"%s\" has invalid password type", frontend->username))); } shadow_pass = pg_be_scram_build_verifier(storedPassword); if (!shadow_pass) ereport(ERROR, - (errmsg("authentication failed"), + (errmsg("authentication failed"), errdetail("faild to build the scram verifier"))); /* @@ -1337,7 +1347,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, initial = true; do { - static int size; + static int size; static char data[MAX_PASSWORD_SIZE]; /* Read password packet */ @@ -1355,7 +1365,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, if (initial) { const char *selected_mech; - char *ptr = data; + char *ptr = data; /* * We only support SCRAM-SHA-256 at the moment, so anything else @@ -1369,7 +1379,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, } /* get the length of trailing optional data */ ptr += strlen(selected_mech) + 1; - memcpy(&inputlen,ptr,sizeof(int)); + memcpy(&inputlen, ptr, sizeof(int)); inputlen = ntohl(inputlen); if (inputlen == -1) input = NULL; @@ -1401,7 +1411,7 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, * Negotiation generated data to be sent to the client. */ ereport(DEBUG4, - (errmsg("sending SASL challenge of length %u", outputlen))); + (errmsg("sending SASL challenge of length %u", outputlen))); if (result == SASL_EXCHANGE_SUCCESS) sendAuthRequest(frontend, frontend->protoVersion, AUTH_REQ_SASL_FIN, output, outputlen); @@ -1416,18 +1426,19 @@ authenticate_frontend_SCRAM(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, if (result != SASL_EXCHANGE_SUCCESS) { ereport(ERROR, - (errmsg("authentication failed"), - errdetail("username \"%s\" or password does not exist in backend",frontend->username))); + (errmsg("authentication failed"), + errdetail("username \"%s\" or password does not exist in backend", frontend->username))); } frontend->frontend_authenticated = true; } -void authenticate_frontend(POOL_CONNECTION *frontend) +void +authenticate_frontend(POOL_CONNECTION * frontend) { switch (frontend->pool_hba->auth_method) { case uaMD5: - authenticate_frontend_md5(NULL,frontend,0,frontend->protoVersion); + authenticate_frontend_md5(NULL, frontend, 0, frontend->protoVersion); break; case uaCert: authenticate_frontend_cert(frontend); @@ -1441,7 +1452,7 @@ void authenticate_frontend(POOL_CONNECTION *frontend) case uaImplicitReject: case uaReject: ereport(ERROR, - (errmsg("authentication with pgpool failed for user \"%s\" rejected",frontend->username))); + (errmsg("authentication with pgpool failed for user \"%s\" rejected", frontend->username))); break; case uaTrust: frontend->frontend_authenticated = true; @@ -1449,57 +1460,60 @@ void authenticate_frontend(POOL_CONNECTION *frontend) } #ifdef USE_SSL -static void authenticate_frontend_cert(POOL_CONNECTION *frontend) +static void +authenticate_frontend_cert(POOL_CONNECTION * frontend) { if (frontend->client_cert_loaded == true && frontend->cert_cn) { ereport(DEBUG1, - (errmsg("connecting user is \"%s\" and ssl certificate CN is \"%s\"",frontend->username,frontend->cert_cn))); - if (strcasecmp(frontend->username,frontend->cert_cn) == 0) + (errmsg("connecting user is \"%s\" and ssl certificate CN is \"%s\"", frontend->username, frontend->cert_cn))); + if (strcasecmp(frontend->username, frontend->cert_cn) == 0) { frontend->frontend_authenticated = true; ereport(LOG, - (errmsg("SSL certificate authentication for user \"%s\" with Pgpool-II is successful",frontend->username))); + (errmsg("SSL certificate authentication for user \"%s\" with Pgpool-II is successful", frontend->username))); return; } else { frontend->frontend_authenticated = false; ereport(LOG, - (errmsg("SSL certificate authentication for user \"%s\" failed",frontend->username))); + (errmsg("SSL certificate authentication for user \"%s\" failed", frontend->username))); } } ereport(ERROR, - (errmsg("CERT authentication failed"), + (errmsg("CERT authentication failed"), errdetail("no valid certificate presented"))); } #else -static void authenticate_frontend_cert(POOL_CONNECTION *frontend) +static void +authenticate_frontend_cert(POOL_CONNECTION * frontend) { ereport(ERROR, - (errmsg("CERT authentication failed"), + (errmsg("CERT authentication failed"), errdetail("CERT authentication is not supported without SSL"))); } #endif -static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +static void +authenticate_frontend_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) { - char salt[4]; - static int size; - char password[MAX_PASSWORD_SIZE]; - char userPassword[MAX_PASSWORD_SIZE]; - char encbuf[POOL_PASSWD_LEN+1]; - char *md5; + char salt[4]; + static int size; + char password[MAX_PASSWORD_SIZE]; + char userPassword[MAX_PASSWORD_SIZE]; + char encbuf[POOL_PASSWD_LEN + 1]; + char *md5; PasswordType storedPasswordType = PASSWORD_TYPE_UNKNOWN; - char *storedPassword = NULL; + char *storedPassword = NULL; if (RAW_MODE || NUM_BACKENDS == 1) { if (backend) do_md5_single_backend(backend, frontend, reauth, protoMajor); - return; /* This will be handled later */ + return; /* This will be handled later */ } if (!frontend->passwordMapping) frontend->passwordMapping = pool_get_user_credentials(frontend->username); @@ -1515,9 +1529,9 @@ static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION else { ereport(FATAL, - (return_code(2), - errmsg("md5 authentication failed"), - errdetail("pool_passwd file does not contain an entry for \"%s\"",frontend->username))); + (return_code(2), + errmsg("md5 authentication failed"), + errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username))); } } else @@ -1532,10 +1546,11 @@ static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION /* Read password packet */ read_password_packet(frontend, frontend->protoVersion, password, &size); - /*If we have clear text password stored in pool_passwd, convert it to md5 */ + /* If we have clear text password stored in pool_passwd, convert it to md5 */ if (storedPasswordType == PASSWORD_TYPE_PLAINTEXT || storedPasswordType == PASSWORD_TYPE_AES) { - char *pwd; + char *pwd; + if (storedPasswordType == PASSWORD_TYPE_AES) { pwd = get_decrypted_password(storedPassword); @@ -1565,18 +1580,18 @@ static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION else { ereport(FATAL, - (return_code(2), - errmsg("md5 authentication failed"), - errdetail("unable to get the password for \"%s\"",frontend->username))); + (return_code(2), + errmsg("md5 authentication failed"), + errdetail("unable to get the password for \"%s\"", frontend->username))); } /* Check the password using my salt + pool_passwd */ - pg_md5_encrypt(md5+strlen("md5"), salt, sizeof(salt), encbuf); + pg_md5_encrypt(md5 + strlen("md5"), salt, sizeof(salt), encbuf); if (strcmp(password, encbuf)) { /* Password does not match */ ereport(ERROR, - (errmsg("md5 authentication failed"), + (errmsg("md5 authentication failed"), errdetail("password does not match"))); } ereport(LOG, @@ -1588,12 +1603,13 @@ static void authenticate_frontend_md5(POOL_CONNECTION *backend, POOL_CONNECTION /* * perform MD5 authentication */ -static int do_md5_single_backend(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +static int +do_md5_single_backend(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor) { - char salt[4]; - static int size; + char salt[4]; + static int size; static char password[MAX_PASSWORD_SIZE]; - int kind; + int kind; if (!reauth) { @@ -1658,8 +1674,9 @@ static int do_md5_single_backend(POOL_CONNECTION *backend, POOL_CONNECTION *fron return kind; } -static bool get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, - char** password, PasswordType *passwordType) +static bool +get_auth_password(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, + char **password, PasswordType *passwordType) { /* First preference is to use the pool_passwd file */ if (frontend->passwordMapping == NULL) @@ -1668,9 +1685,8 @@ static bool get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *fronten if (frontend->passwordMapping == NULL) { /* - * check if we have password stored in the - * frontend connection. - * that could come by using the clear text auth + * check if we have password stored in the frontend connection. that + * could come by using the clear text auth */ if (frontend->pwd_size > 0 && frontend->passwordType == PASSWORD_TYPE_PLAINTEXT) { @@ -1697,15 +1713,16 @@ static bool get_auth_password(POOL_CONNECTION *backend, POOL_CONNECTION *fronten /* * perform MD5 authentication */ -static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor, - char *storedPassword, PasswordType passwordType) +static int +do_md5(POOL_CONNECTION * backend, POOL_CONNECTION * frontend, int reauth, int protoMajor, + char *storedPassword, PasswordType passwordType) { - char salt[4]; + char salt[4]; static char userPassword[MAX_PASSWORD_SIZE]; - int kind; - bool password_decrypted = false; - char encbuf[POOL_PASSWD_LEN+1]; - char *pool_passwd = NULL; + int kind; + bool password_decrypted = false; + char encbuf[POOL_PASSWD_LEN + 1]; + char *pool_passwd = NULL; if (NUM_BACKENDS == 1) return do_md5_single_backend(backend, frontend, reauth, protoMajor); @@ -1713,8 +1730,7 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut if (passwordType == PASSWORD_TYPE_AES) { /* - * decrypt the stored AES password - * for comparing it + * decrypt the stored AES password for comparing it */ storedPassword = get_decrypted_password(storedPassword); if (storedPassword == NULL) @@ -1740,17 +1756,17 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut else { ereport(ERROR, - (errmsg("md5 authentication failed"), + (errmsg("md5 authentication failed"), errdetail("unable to get the password"))); } /* master? */ - if (IS_MASTER_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false ) + if (IS_MASTER_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false) { /* - * If frontend is not authenticated and do it it first. - * but if we have already received the password from frontend - * using the clear text auth, we may not need to authenticate it + * If frontend is not authenticated and do it it first. but if we have + * already received the password from frontend using the clear text + * auth, we may not need to authenticate it */ if (pool_config->allow_clear_text_frontend_auth && frontend->auth_kind == AUTH_REQ_PASSWORD && @@ -1762,7 +1778,7 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut /* save this password in backend for the re-auth */ backend->pwd_size = frontend->pwd_size; memcpy(backend->password, frontend->password, frontend->pwd_size); - backend->password[backend->pwd_size] = 0; /* null terminate */ + backend->password[backend->pwd_size] = 0; /* null terminate */ backend->passwordType = frontend->passwordType; } else @@ -1781,18 +1797,18 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut pool_read(backend, salt, sizeof(salt)); ereport(DEBUG2, - (errmsg("performing md5 authentication"), - errdetail("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id, - salt[0], salt[1], salt[2], salt[3]))); + (errmsg("performing md5 authentication"), + errdetail("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id, + salt[0], salt[1], salt[2], salt[3]))); /* Encrypt password in pool_passwd using the salt */ - pg_md5_encrypt(pool_passwd+strlen("md5"), salt, sizeof(salt), encbuf); + pg_md5_encrypt(pool_passwd + strlen("md5"), salt, sizeof(salt), encbuf); /* Send password packet to backend and receive auth response */ kind = send_password_packet(backend, protoMajor, encbuf); if (kind < 0) ereport(ERROR, - (errmsg("md5 authentication failed"), + (errmsg("md5 authentication failed"), errdetail("backend replied with invalid kind"))); } @@ -1818,14 +1834,15 @@ static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reaut * Send an authentication request packet to the frontend. */ static void -sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen) +sendAuthRequest(POOL_CONNECTION * frontend, int protoMajor, int32 auth_req_type, char *extradata, int extralen) { - int kind = htonl(auth_req_type); + int kind = htonl(auth_req_type); pool_write(frontend, "R", 1); /* authentication */ if (protoMajor == PROTO_MAJOR_V3) { - int len = 8 + extralen; + int len = 8 + extralen; + len = htonl(len); pool_write(frontend, &len, sizeof(len)); } @@ -1840,7 +1857,7 @@ sendAuthRequest(POOL_CONNECTION *frontend, int protoMajor, int32 auth_req_type, * Send md5 authentication request packet to frontend */ static void -send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt) +send_md5auth_request(POOL_CONNECTION * frontend, int protoMajor, char *salt) { sendAuthRequest(frontend, protoMajor, AUTH_REQ_MD5, salt, 4); } @@ -1849,9 +1866,10 @@ send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt) /* * Read password packet from frontend */ -static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *password, int *pwdSize) +static int +read_password_packet(POOL_CONNECTION * frontend, int protoMajor, char *password, int *pwdSize) { - int size; + int size; /* Read password packet */ if (protoMajor == PROTO_MAJOR_V2) @@ -1860,13 +1878,13 @@ static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char } else { - char k; + char k; pool_read(frontend, &k, sizeof(k)); if (k != 'p') - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid authentication packet. password packet does not start with \"p\""))); + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid authentication packet. password packet does not start with \"p\""))); pool_read(frontend, &size, sizeof(size)); } @@ -1874,21 +1892,22 @@ static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char *pwdSize = ntohl(size) - 4; if (*pwdSize > MAX_PASSWORD_SIZE) { - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid authentication packet. password is too long. password length is %d", *pwdSize))); + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid authentication packet. password is too long. password length is %d", *pwdSize))); + /* * We do not read to throw away packet here. Since it is possible that * it's a denial of service attack. */ } else if (*pwdSize <= 0) - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid authentication packet. invalid password length. password length is %d", *pwdSize))); + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid authentication packet. invalid password length. password length is %d", *pwdSize))); pool_read(frontend, password, *pwdSize); - + password[*pwdSize] = '\0'; return 0; @@ -1900,39 +1919,41 @@ static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, char * response. If it's 0, authentication was successful. * "password" must be null-terminated. */ -static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password) +static int +send_password_packet(POOL_CONNECTION * backend, int protoMajor, char *password) { - int size; - int len; - int kind; - char response; + int size; + int len; + int kind; + char response; /* Send password packet to backend */ if (protoMajor == PROTO_MAJOR_V3) pool_write(backend, "p", 1); - size = htonl(sizeof(size) + strlen(password)+1); + size = htonl(sizeof(size) + strlen(password) + 1); pool_write(backend, &size, sizeof(size)); - pool_write_and_flush(backend, password, strlen(password)+1); + pool_write_and_flush(backend, password, strlen(password) + 1); pool_read(backend, &response, sizeof(response)); if (response != 'R') { - if(response == 'E') /* Backend has thrown an error instead */ + if (response == 'E') /* Backend has thrown an error instead */ { - char* message = NULL; + char *message = NULL; + if (pool_extract_error_message(false, backend, protoMajor, false, &message) == 1) { ereport(ERROR, (errmsg("authentication failed"), - errdetail("%s",message?message:"backend throws authentication error"))); + errdetail("%s", message ? message : "backend throws authentication error"))); } if (message) pfree(message); } - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid backend response. Response does not replied with \"R\""))); + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid backend response. Response does not replied with \"R\""))); } if (protoMajor == PROTO_MAJOR_V3) @@ -1940,9 +1961,9 @@ static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char * pool_read(backend, &len, sizeof(len)); if (ntohl(len) != 8) - ereport(ERROR, - (errmsg("authentication failed"), - errdetail("invalid authentication packet. incorrect authentication packet size (%d)", ntohl(len)))); + ereport(ERROR, + (errmsg("authentication failed"), + errdetail("invalid authentication packet. incorrect authentication packet size (%d)", ntohl(len)))); } /* Expect to read "Authentication OK" response. kind should be 0... */ @@ -1954,9 +1975,10 @@ static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char * /* * Send auth ok to frontend */ -static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor) +static int +send_auth_ok(POOL_CONNECTION * frontend, int protoMajor) { - int msglen; + int msglen; pool_write(frontend, "R", 1); @@ -1974,20 +1996,22 @@ static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor) /* * read message length (V3 only) */ -int pool_read_message_length(POOL_CONNECTION_POOL *cp) +int +pool_read_message_length(POOL_CONNECTION_POOL * cp) { - int length, length0; - int i; + int length, + length0; + int i; /* read message from master node */ pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0)); length0 = ntohl(length0); ereport(DEBUG5, - (errmsg("reading message length"), + (errmsg("reading message length"), errdetail("slot: %d length: %d", MASTER_NODE_ID, length0))); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i)) { @@ -1998,20 +2022,20 @@ int pool_read_message_length(POOL_CONNECTION_POOL *cp) length = ntohl(length); ereport(DEBUG5, - (errmsg("reading message length"), + (errmsg("reading message length"), errdetail("slot: %d length: %d", i, length))); if (length != length0) - ereport(ERROR, - (errmsg("unable to read message length"), - errdetail("message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0))); - + ereport(ERROR, + (errmsg("unable to read message length"), + errdetail("message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0))); + } if (length0 < 0) - ereport(ERROR, - (errmsg("unable to read message length"), - errdetail("invalid message length (%d)", length))); + ereport(ERROR, + (errmsg("unable to read message length"), + errdetail("invalid message length (%d)", length))); return length0; } @@ -2021,11 +2045,13 @@ int pool_read_message_length(POOL_CONNECTION_POOL *cp) * unlike pool_read_message_length, this returns an array of message length. * The array is in the static storage, thus it will be destroyed by subsequent calls. */ -int *pool_read_message_length2(POOL_CONNECTION_POOL *cp) +int * +pool_read_message_length2(POOL_CONNECTION_POOL * cp) { - int length, length0; - int i; - static int length_array[MAX_CONNECTION_SLOTS]; + int length, + length0; + int i; + static int length_array[MAX_CONNECTION_SLOTS]; /* read message from master node */ pool_read(CONNECTION(cp, MASTER_NODE_ID), &length0, sizeof(length0)); @@ -2033,10 +2059,10 @@ int *pool_read_message_length2(POOL_CONNECTION_POOL *cp) length0 = ntohl(length0); length_array[MASTER_NODE_ID] = length0; ereport(DEBUG5, - (errmsg("reading message length"), + (errmsg("reading message length"), errdetail("master slot: %d length: %d", MASTER_NODE_ID, length0))); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { @@ -2044,21 +2070,21 @@ int *pool_read_message_length2(POOL_CONNECTION_POOL *cp) length = ntohl(length); ereport(DEBUG5, - (errmsg("reading message length"), + (errmsg("reading message length"), errdetail("master slot: %d length: %d", i, length))); if (length != length0) { ereport(LOG, - (errmsg("reading message length"), - errdetail("message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0))); + (errmsg("reading message length"), + errdetail("message length (%d) in slot %d does not match with slot 0(%d)", length, i, length0))); } if (length < 0) { - ereport(ERROR, - (errmsg("unable to read message length"), - errdetail("invalid message length (%d)", length))); + ereport(ERROR, + (errmsg("unable to read message length"), + errdetail("invalid message length (%d)", length))); } length_array[i] = length; @@ -2068,15 +2094,17 @@ int *pool_read_message_length2(POOL_CONNECTION_POOL *cp) return &length_array[0]; } -signed char pool_read_kind(POOL_CONNECTION_POOL *cp) +signed char +pool_read_kind(POOL_CONNECTION_POOL * cp) { - char kind0, kind; - int i; + char kind0, + kind; + int i; kind = -1; kind0 = 0; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) { @@ -2093,14 +2121,14 @@ signed char pool_read_kind(POOL_CONNECTION_POOL *cp) { if (kind != kind0) { - char *message; + char *message; if (kind0 == 'E') { if (pool_extract_error_message(false, MASTER(cp), MAJOR(cp), true, &message) == 1) { - ereport(LOG, - (errmsg("pool_read_kind: error message from master backend:%s", message))); + ereport(LOG, + (errmsg("pool_read_kind: error message from master backend:%s", message))); pfree(message); } } @@ -2108,14 +2136,14 @@ signed char pool_read_kind(POOL_CONNECTION_POOL *cp) { if (pool_extract_error_message(false, CONNECTION(cp, i), MAJOR(cp), true, &message) == 1) { - ereport(LOG, - (errmsg("pool_read_kind: error message from %d th backend:%s", i, message))); + ereport(LOG, + (errmsg("pool_read_kind: error message from %d th backend:%s", i, message))); pfree(message); } } - ereport(ERROR, - (errmsg("unable to read message kind"), - errdetail("kind does not match between master(%x) slot[%d] (%x)",kind0, i, kind))); + ereport(ERROR, + (errmsg("unable to read message kind"), + errdetail("kind does not match between master(%x) slot[%d] (%x)", kind0, i, kind))); } } } @@ -2123,15 +2151,17 @@ signed char pool_read_kind(POOL_CONNECTION_POOL *cp) return kind; } -int pool_read_int(POOL_CONNECTION_POOL *cp) +int +pool_read_int(POOL_CONNECTION_POOL * cp) { - int data0, data; - int i; + int data0, + data; + int i; data = -1; data0 = 0; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) { @@ -2146,9 +2176,9 @@ int pool_read_int(POOL_CONNECTION_POOL *cp) { if (data != data0) { - ereport(ERROR, - (errmsg("unable to read int value"), - errdetail("data does not match between between master(%x) slot[%d] (%x)", data0, i, data))); + ereport(ERROR, + (errmsg("unable to read int value"), + errdetail("data does not match between between master(%x) slot[%d] (%x)", data0, i, data))); } } @@ -2159,18 +2189,20 @@ int pool_read_int(POOL_CONNECTION_POOL *cp) void pool_random(void *buf, size_t len) { - int ret = 0; + int ret = 0; #ifdef USE_SSL ret = RAND_bytes(buf, len); #endif /* if RND_bytes fails or not present use the old technique */ - if ( ret == 0) + if (ret == 0) { - int i; - char *ptr = buf; + int i; + char *ptr = buf; + for (i = 0; i < len; i++) { - long rand = PostmasterRandom(); + long rand = PostmasterRandom(); + ptr[i] = (rand % 255) + 1; } } @@ -2179,9 +2211,10 @@ pool_random(void *buf, size_t len) /* * pool_random_salt */ -void pool_random_salt(char *md5Salt) +void +pool_random_salt(char *md5Salt) { - pool_random(md5Salt,4); + pool_random(md5Salt, 4); } /* @@ -2223,35 +2256,36 @@ PostmasterRandom(void) } -static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoMajor, int message_length, - char *username, char *storedPassword, PasswordType passwordType) +static bool +do_SCRAM(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoMajor, int message_length, + char *username, char *storedPassword, PasswordType passwordType) { /* read the packet first */ - void *sasl_state = NULL; - int payload_len = message_length - 4 - 4; - int auth_kind = AUTH_REQ_SASL; - char payload[MAX_SASL_PAYLOAD_LEN]; + void *sasl_state = NULL; + int payload_len = message_length - 4 - 4; + int auth_kind = AUTH_REQ_SASL; + char payload[MAX_SASL_PAYLOAD_LEN]; if (passwordType != PASSWORD_TYPE_PLAINTEXT) { ereport(ERROR, - (errmsg("SCRAM authentication failed"), + (errmsg("SCRAM authentication failed"), errdetail("invalid password type"))); } if (storedPassword == NULL) { ereport(ERROR, - (errmsg("SCRAM authentication failed"), + (errmsg("SCRAM authentication failed"), errdetail("password not found"))); } /* master? */ - if (frontend && IS_MASTER_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false ) + if (frontend && IS_MASTER_NODE_ID(backend->db_node_id) && frontend->frontend_authenticated == false) { /* - * If frontend is not authenticated and do it it first. - * but if we have already received the password from frontend - * using the clear text auth, we may not need to authenticate it + * If frontend is not authenticated and do it it first. but if we have + * already received the password from frontend using the clear text + * auth, we may not need to authenticate it */ if (pool_config->allow_clear_text_frontend_auth && frontend->auth_kind == AUTH_REQ_PASSWORD && @@ -2263,7 +2297,7 @@ static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int pr /* save this password in backend for the re-auth */ backend->pwd_size = frontend->pwd_size; memcpy(backend->password, frontend->password, frontend->pwd_size); - backend->password[backend->pwd_size] = 0; /* null terminate */ + backend->password[backend->pwd_size] = 0; /* null terminate */ backend->passwordType = frontend->passwordType; } else @@ -2272,25 +2306,30 @@ static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int pr } } - for(;;) + for (;;) { - char kind; - int len; + char kind; + int len; - /* at this point we have already read kind, message length and authkind */ + /* + * at this point we have already read kind, message length and + * authkind + */ if (payload_len > MAX_SASL_PAYLOAD_LEN) ereport(ERROR, (errmsg("invalid authentication data too big"))); pool_read(backend, payload, payload_len); - switch (auth_kind) { + switch (auth_kind) + { case AUTH_REQ_OK: /* Save the auth info in backend */ backend->auth_kind = AUTH_REQ_SASL; return true; break; case AUTH_REQ_SASL: + /* * The request contains the name (as assigned by IANA) of the * authentication mechanism. @@ -2312,7 +2351,7 @@ static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int pr (errmsg("invalid authentication request from server: AUTH_REQ_SASL_CONT without AUTH_REQ_SASL"))); return false; } - if (pg_SASL_continue(backend, payload, payload_len, sasl_state, (auth_kind == AUTH_REQ_SASL_FIN))!= 0) + if (pg_SASL_continue(backend, payload, payload_len, sasl_state, (auth_kind == AUTH_REQ_SASL_FIN)) != 0) { /* Use error message, if set already */ ereport(ERROR, @@ -2322,15 +2361,15 @@ static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int pr break; default: ereport(ERROR, - (errmsg("invalid authentication request from server: unknown auth kind %d",auth_kind))); - } + (errmsg("invalid authentication request from server: unknown auth kind %d", auth_kind))); + } /* Read next packend */ pool_read(backend, &kind, sizeof(kind)); pool_read(backend, &len, sizeof(len)); if (kind != 'R') ereport(ERROR, (errmsg("backend authentication failed"), - errdetail("backend response with kind \'%c\' when expecting \'R\'",kind))); + errdetail("backend response with kind \'%c\' when expecting \'R\'", kind))); message_length = ntohl(len); if (len <= 8) ereport(ERROR, @@ -2344,18 +2383,18 @@ static bool do_SCRAM(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int pr return false; } -static void* -pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *username, char* storedPassword) +static void * +pg_SASL_init(POOL_CONNECTION * backend, char *payload, int payloadlen, char *username, char *storedPassword) { char *initialresponse = NULL; int initialresponselen; bool done; bool success; const char *selected_mechanism; - char *mechanism_buf = payload; - void *sasl_state = NULL; - int size; - int send_msg_len; + char *mechanism_buf = payload; + void *sasl_state = NULL; + int size; + int send_msg_len; /* * Parse the list of SASL authentication mechanisms in the @@ -2381,9 +2420,9 @@ pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *user */ if (strcmp(mechanism_buf, SCRAM_SHA_256_NAME) == 0) { - /* This is the password which we need to send to the PG backend - * for authentication. - * It is stored in the file + /* + * This is the password which we need to send to the PG backend + * for authentication. It is stored in the file */ if (storedPassword == NULL || storedPassword[0] == '\0') { @@ -2397,7 +2436,7 @@ pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *user (errmsg("SASL authentication error\n"))); selected_mechanism = SCRAM_SHA_256_NAME; } - mechanism_buf += strlen(mechanism_buf) +1; + mechanism_buf += strlen(mechanism_buf) + 1; } if (!selected_mechanism) @@ -2427,7 +2466,7 @@ pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *user pool_write(backend, "p", 1); pool_write(backend, &size, sizeof(size)); - pool_write(backend, (void*)selected_mechanism, strlen(selected_mechanism)+1); + pool_write(backend, (void *) selected_mechanism, strlen(selected_mechanism) + 1); if (initialresponse) { size = htonl(initialresponselen); @@ -2448,7 +2487,7 @@ pg_SASL_init(POOL_CONNECTION *backend, char *payload, int payloadlen, char *user * the protocol. */ static int -pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void *sasl_state, bool final) +pg_SASL_continue(POOL_CONNECTION * backend, char *payload, int payloadlen, void *sasl_state, bool final) { char *output; int outputlen; @@ -2458,7 +2497,7 @@ pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void * /* Read the SASL challenge from the AuthenticationSASLContinue message. */ challenge = palloc(payloadlen + 1); - memcpy(challenge,payload,payloadlen); + memcpy(challenge, payload, payloadlen); challenge[payloadlen] = '\0'; /* For safety and convenience, ensure the buffer is NULL-terminated. */ @@ -2483,7 +2522,7 @@ pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void * /* * Send the SASL response to the server. */ - int size = htonl(outputlen + 4); + int size = htonl(outputlen + 4); pool_write(backend, "p", 1); pool_write(backend, &size, sizeof(size)); @@ -2498,4 +2537,3 @@ pg_SASL_continue(POOL_CONNECTION *backend, char *payload, int payloadlen, void * return 0; } - diff --git a/src/auth/pool_hba.c b/src/auth/pool_hba.c index 9e559a6d6..7a28ae060 100644 --- a/src/auth/pool_hba.c +++ b/src/auth/pool_hba.c @@ -43,7 +43,7 @@ #include "parser/pg_list.h" #include "auth/pool_passwd.h" -#define MULTI_VALUE_SEP "\001" /* delimiter for multi-valued column strings */ +#define MULTI_VALUE_SEP "\001" /* delimiter for multi-valued column strings */ #define MAX_TOKEN 256 #define MAX_LINE 8192 @@ -82,6 +82,7 @@ typedef struct HbaToken char *string; bool quoted; } HbaToken; + /* callback data for check_network_callback */ typedef struct check_network_data { @@ -91,48 +92,41 @@ typedef struct check_network_data } check_network_data; -static HbaToken * -copy_hba_token(HbaToken *in); -static HbaToken * -make_hba_token(const char *token, bool quoted); +static HbaToken *copy_hba_token(HbaToken *in); +static HbaToken *make_hba_token(const char *token, bool quoted); -static bool -parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, +static bool parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg); static MemoryContext tokenize_file(const char *filename, FILE *file, - List **tok_lines, int elevel); -static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq); -static void auth_failed(POOL_CONNECTION *frontend); + List **tok_lines, int elevel); +static void sendAuthRequest(POOL_CONNECTION * frontend, AuthRequest areq); +static void auth_failed(POOL_CONNECTION * frontend); static void close_all_backend_connections(void); -static bool hba_getauthmethod(POOL_CONNECTION *frontend); -static bool check_hba(POOL_CONNECTION *frontend); +static bool hba_getauthmethod(POOL_CONNECTION * frontend); +static bool check_hba(POOL_CONNECTION * frontend); static bool check_user(char *user, List *tokens); static bool check_db(const char *dbname, const char *user, List *tokens); -static List * tokenize_inc_file(List *tokens, +static List *tokenize_inc_file(List *tokens, const char *outer_filename, const char *inc_filename, int elevel, - char **err_msg); + char **err_msg); static bool -check_hostname(POOL_CONNECTION *frontend, const char *hostname); + check_hostname(POOL_CONNECTION * frontend, const char *hostname); static bool -check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask); + check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask); static bool -check_same_host_or_net(SockAddr *raddr, IPCompareMethod method); -static void -check_network_callback(struct sockaddr *addr, struct sockaddr *netmask, + check_same_host_or_net(SockAddr *raddr, IPCompareMethod method); +static void check_network_callback(struct sockaddr *addr, struct sockaddr *netmask, void *cb_data); -static HbaLine * -parse_hba_line(TokenizedLine *tok_line, int elevel); +static HbaLine *parse_hba_line(TokenizedLine *tok_line, int elevel); static bool pg_isblank(const char c); -static bool -next_token(char **lineptr, char *buf, int bufsz, +static bool next_token(char **lineptr, char *buf, int bufsz, bool *initial_quote, bool *terminating_comma, int elevel, char **err_msg); -static List * -next_field_expand(const char *filename, char **lineptr, +static List *next_field_expand(const char *filename, char **lineptr, int elevel, char **err_msg); static POOL_STATUS CheckUserExist(char *username); @@ -146,25 +140,26 @@ static POOL_STATUS CheckUserExist(char *username); #define PGPOOL_PAM_SERVICE "pgpool" /* Service name passed to PAM */ -static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password); -static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, struct pam_response ** resp, void *appdata_ptr); +static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *password); +static int pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr); + /* * recv_password_packet is usually used with authentications that require a client * password. However, pgpool's hba function only uses it for PAM authentication, * so declare a prototype here in "#ifdef USE_PAM" to avoid compilation warning. */ -static char *recv_password_packet(POOL_CONNECTION *frontend); +static char *recv_password_packet(POOL_CONNECTION * frontend); static struct pam_conv pam_passw_conv = { &pam_passwd_conv_proc, NULL }; -static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */ -static POOL_CONNECTION *pam_frontend_kludge; /* Workaround for passing - * POOL_CONNECTION *frontend - * into pam_passwd_conv_proc */ -#endif /* USE_PAM */ +static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */ +static POOL_CONNECTION * pam_frontend_kludge; /* Workaround for passing + * POOL_CONNECTION *frontend + * into pam_passwd_conv_proc */ +#endif /* USE_PAM */ /* @@ -507,7 +502,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) } if (SockAddr_cidr_mask(&parsedline->mask, cidr_slash + 1, - parsedline->addr.ss_family) < 0) + parsedline->addr.ss_family) < 0) { ereport(elevel, (errcode(ERRCODE_CONFIG_FILE_ERROR), @@ -551,7 +546,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) token = linitial(tokens); ret = getaddrinfo_all(token->string, NULL, - &hints, &gai_result); + &hints, &gai_result); if (ret || !gai_result) { ereport(elevel, @@ -670,7 +665,7 @@ parse_hba_line(TokenizedLine *tok_line, int elevel) *val++ = '\0'; /* str now holds "name", val holds "value" */ if (!parse_hba_auth_opt(str, val, parsedline, elevel, err_msg)) { - /* parse_hba_auth_opt already logged the error message */ + /* parse_hba_auth_opt already logged the error message */ pfree(str); return NULL; } @@ -692,6 +687,7 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, int elevel, char **err_msg) { int line_num = hbaline->linenumber; + if (strcmp(name, "pamservice") == 0) { #ifdef USE_PAM @@ -761,84 +757,84 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, /* * do frontend <-> pgpool authentication based on pool_hba.conf */ -void ClientAuthentication(POOL_CONNECTION *frontend) +void +ClientAuthentication(POOL_CONNECTION * frontend) { POOL_STATUS status = POOL_END; + PG_TRY(); - { - if (! hba_getauthmethod(frontend)) - ereport(FATAL, - (return_code(2), - errmsg("client authentication failed"), - errdetail("missing or erroneous pool_hba.conf file"), - errhint("see pgpool log for details"))); + { + if (!hba_getauthmethod(frontend)) + ereport(FATAL, + (return_code(2), + errmsg("client authentication failed"), + errdetail("missing or erroneous pool_hba.conf file"), + errhint("see pgpool log for details"))); /* - * Get the password for the user if it is stored - * in the pool_password file + * Get the password for the user if it is stored in the pool_password + * file */ frontend->passwordMapping = pool_get_user_credentials(frontend->username); - switch (frontend->pool_hba->auth_method) - { + switch (frontend->pool_hba->auth_method) + { case uaImplicitReject: - case uaReject: - { - /* - * This could have come from an explicit "reject" entry in - * pool_hba.conf, but more likely it means there was no matching - * entry. Take pity on the poor user and issue a helpful - * error message. NOTE: this is not a security breach, - * because all the info reported here is known at the frontend - * and must be assumed known to bad guys. We're merely helping - * out the less clueful good guys. - */ - char hostinfo[NI_MAXHOST]; - char *errmessage; - int messagelen; - - getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen, - hostinfo, sizeof(hostinfo), - NULL, 0, - NI_NUMERICHOST); - - messagelen = sizeof(hostinfo) + - strlen(frontend->username) + strlen(frontend->database) + 80; - errmessage = (char *)palloc(messagelen+1); + case uaReject: + { + /* + * This could have come from an explicit "reject" entry in + * pool_hba.conf, but more likely it means there was no + * matching entry. Take pity on the poor user and issue a + * helpful error message. NOTE: this is not a security + * breach, because all the info reported here is known at + * the frontend and must be assumed known to bad guys. + * We're merely helping out the less clueful good guys. + */ + char hostinfo[NI_MAXHOST]; + char *errmessage; + int messagelen; + + getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen, + hostinfo, sizeof(hostinfo), + NULL, 0, + NI_NUMERICHOST); + + messagelen = sizeof(hostinfo) + + strlen(frontend->username) + strlen(frontend->database) + 80; + errmessage = (char *) palloc(messagelen + 1); #ifdef USE_SSL - snprintf(errmessage, messagelen+7, /* +7 is for "SSL off" */ - "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s", - hostinfo, frontend->username, frontend->database, - frontend->ssl ? "SSL on" : "SSL off"); + snprintf(errmessage, messagelen + 7, /* +7 is for "SSL off" */ + "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s", + hostinfo, frontend->username, frontend->database, + frontend->ssl ? "SSL on" : "SSL off"); #else - snprintf(errmessage, messagelen, - "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"", - hostinfo, frontend->username, frontend->database); + snprintf(errmessage, messagelen, + "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"", + hostinfo, frontend->username, frontend->database); #endif - ereport(FATAL, - (return_code(2), - errmsg("client authentication failed"), - errdetail("%s",errmessage), - errhint("see pgpool log for details"))); - break; - } - - /*case uaKrb4: - case uaKrb5: - case uaIdent: - case uaCrypt: - */ - case uaPassword: + ereport(FATAL, + (return_code(2), + errmsg("client authentication failed"), + errdetail("%s", errmessage), + errhint("see pgpool log for details"))); + break; + } + + /* + * case uaKrb4: case uaKrb5: case uaIdent: case uaCrypt: + */ + case uaPassword: ereport(DEBUG1, (errmsg("password authentication required"))); status = POOL_CONTINUE; - break; + break; case uaCert: ereport(DEBUG1, (errmsg("SSL certificate authentication required"))); status = POOL_CONTINUE; break; - case uaMD5: + case uaMD5: status = POOL_CONTINUE; if (NUM_BACKENDS <= 1) @@ -846,74 +842,75 @@ void ClientAuthentication(POOL_CONNECTION *frontend) if (!frontend->passwordMapping) ereport(FATAL, - (return_code(2), - errmsg("md5 authentication failed"), - errdetail("pool_passwd file does not contain an entry for \"%s\"",frontend->username))); + (return_code(2), + errmsg("md5 authentication failed"), + errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username))); if (frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_PLAINTEXT && frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_MD5 && frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_AES) ereport(FATAL, - (return_code(2), - errmsg("md5 authentication failed"), - errdetail("pool_passwd file does not contain valid md5 entry for \"%s\"",frontend->username))); - break; + (return_code(2), + errmsg("md5 authentication failed"), + errdetail("pool_passwd file does not contain valid md5 entry for \"%s\"", frontend->username))); + break; case uaSCRAM: if (!frontend->passwordMapping) ereport(FATAL, - (return_code(2), - errmsg("SCRAM authentication failed"), - errdetail("pool_passwd file does not contain an entry for \"%s\"",frontend->username))); + (return_code(2), + errmsg("SCRAM authentication failed"), + errdetail("pool_passwd file does not contain an entry for \"%s\"", frontend->username))); if (frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_PLAINTEXT && frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_SCRAM_SHA_256 && frontend->passwordMapping->pgpoolUser.passwordType != PASSWORD_TYPE_AES) ereport(FATAL, - (return_code(2), - errmsg("SCRAM authentication failed"), - errdetail("pool_passwd file does not contain valid SCRAM entry for \"%s\"",frontend->username))); + (return_code(2), + errmsg("SCRAM authentication failed"), + errdetail("pool_passwd file does not contain valid SCRAM entry for \"%s\"", frontend->username))); status = POOL_CONTINUE; break; - #ifdef USE_PAM - case uaPAM: - pam_frontend_kludge = frontend; - status = CheckPAMAuth(frontend, frontend->username, ""); - break; - #endif /* USE_PAM */ - - case uaTrust: - status = POOL_CONTINUE; - break; - } - } - PG_CATCH(); - { - close_all_backend_connections(); - PG_RE_THROW(); - } - PG_END_TRY(); - - if (status == POOL_CONTINUE) +#ifdef USE_PAM + case uaPAM: + pam_frontend_kludge = frontend; + status = CheckPAMAuth(frontend, frontend->username, ""); + break; +#endif /* USE_PAM */ + + case uaTrust: + status = POOL_CONTINUE; + break; + } + } + PG_CATCH(); { - sendAuthRequest(frontend, AUTH_REQ_OK); + close_all_backend_connections(); + PG_RE_THROW(); + } + PG_END_TRY(); + + if (status == POOL_CONTINUE) + { + sendAuthRequest(frontend, AUTH_REQ_OK); authenticate_frontend(frontend); } - else + else auth_failed(frontend); } -static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq) +static void +sendAuthRequest(POOL_CONNECTION * frontend, AuthRequest areq) { - int wsize; /* number of bytes to write */ - int areq_nbo; /* areq in network byte order */ + int wsize; /* number of bytes to write */ + int areq_nbo; /* areq in network byte order */ /* - * If AUTH_REQ_OK, then frontend is OK to connect __with_pgpool__. - * Do not send 'R' to the frontend, he still needs to authenticate - * himself with the backend. + * If AUTH_REQ_OK, then frontend is OK to connect __with_pgpool__. Do not + * send 'R' to the frontend, he still needs to authenticate himself with + * the backend. */ if (areq == AUTH_REQ_OK) return; @@ -928,7 +925,7 @@ static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq) /* else if (areq == AUTH_REQ_CRYPT) */ /* wsize = htonl(sizeof(int)*2+2); */ /* else */ - wsize = htonl(sizeof(int)*2); + wsize = htonl(sizeof(int) * 2); pool_write(frontend, &wsize, sizeof(int)); } @@ -952,16 +949,17 @@ static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq) * * Returns NULL if couldn't get password, else palloc'd string. */ -static char *recv_password_packet(POOL_CONNECTION *frontend) +static char * +recv_password_packet(POOL_CONNECTION * frontend) { - int rsize; - char *passwd; - char *returnVal; + int rsize; + char *passwd; + char *returnVal; if (frontend->protoVersion == PROTO_MAJOR_V3) { /* Expect 'p' message type */ - char kind; + char kind; if (pool_read(frontend, &kind, 1) < 0) return NULL; @@ -969,7 +967,7 @@ static char *recv_password_packet(POOL_CONNECTION *frontend) if (kind != 'p') { ereport(LOG, - (errmsg("unexpected password response received. expected 'p' received '%c'",kind))); + (errmsg("unexpected password response received. expected 'p' received '%c'", kind))); return NULL; /* bad message type */ } } @@ -979,35 +977,36 @@ static char *recv_password_packet(POOL_CONNECTION *frontend) return NULL; rsize = ntohl(rsize) - 4; - passwd = pool_read2(frontend, rsize); /* retrieve password */ + passwd = pool_read2(frontend, rsize); /* retrieve password */ if (passwd == NULL) return NULL; /* Do not echo password to logs, for security. */ ereport(DEBUG1, - (errmsg("received password packet from frontend for pgpool's HBA"))); + (errmsg("received password packet from frontend for pgpool's HBA"))); /* * Return the received string. Note we do not attempt to do any - * character-set conversion on it; since we don't yet know the - * client's encoding, there wouldn't be much point. + * character-set conversion on it; since we don't yet know the client's + * encoding, there wouldn't be much point. */ returnVal = pstrdup(passwd); return returnVal; } -#endif /* USE_PAM */ +#endif /* USE_PAM */ /* * Tell the user the authentication failed. */ -static void auth_failed(POOL_CONNECTION *frontend) +static void +auth_failed(POOL_CONNECTION * frontend) { - int messagelen; - char *errmessage; + int messagelen; + char *errmessage; messagelen = strlen(frontend->username) + 100; - errmessage = (char *)palloc(messagelen+1); + errmessage = (char *) palloc(messagelen + 1); switch (frontend->pool_hba->auth_method) { @@ -1037,7 +1036,7 @@ static void auth_failed(POOL_CONNECTION *frontend) /* "Ident authentication with pgpool failed for user \"%s\"", */ /* frontend->username); */ /* break; */ - case uaMD5: + case uaMD5: snprintf(errmessage, messagelen, "\"MD5\" authentication with pgpool failed for user \"%s\"", frontend->username); @@ -1067,7 +1066,7 @@ static void auth_failed(POOL_CONNECTION *frontend) "PAM authentication with pgpool failed for user \"%s\"", frontend->username); break; -#endif /* USE_PAM */ +#endif /* USE_PAM */ default: snprintf(errmessage, messagelen, "authentication with pgpool failed for user \"%s\": invalid authentication method", @@ -1075,11 +1074,11 @@ static void auth_failed(POOL_CONNECTION *frontend) break; } close_all_backend_connections(); - ereport(FATAL, - (return_code(2), - errmsg("client authentication failed"), - errdetail("%s",errmessage), - errhint("see pgpool log for details"))); + ereport(FATAL, + (return_code(2), + errmsg("client authentication failed"), + errdetail("%s", errmessage), + errhint("see pgpool log for details"))); } @@ -1089,16 +1088,17 @@ static void auth_failed(POOL_CONNECTION *frontend) * * This is exactly the same as send_frontend_exits() in child.c. */ -static void close_all_backend_connections(void) +static void +close_all_backend_connections(void) { - int i; + int i; POOL_CONNECTION_POOL *p = pool_connection_pool; pool_sigset_t oldmask; POOL_SETMASK2(&BlockSig, &oldmask); - for (i=0;i<pool_config->max_pool;i++, p++) + for (i = 0; i < pool_config->max_pool; i++, p++) { if (!MASTER_CONNECTION(p)) continue; @@ -1120,7 +1120,8 @@ static void close_all_backend_connections(void) * If the file is OK but does not contain any entry matching the request, * we return true and method = uaReject. */ -static bool hba_getauthmethod(POOL_CONNECTION *frontend) +static bool +hba_getauthmethod(POOL_CONNECTION * frontend) { if (check_hba(frontend)) return true; @@ -1134,7 +1135,7 @@ static bool hba_getauthmethod(POOL_CONNECTION *frontend) * request. */ static bool -check_hba(POOL_CONNECTION *frontend) +check_hba(POOL_CONNECTION * frontend) { ListCell *line; HbaLine *hba; @@ -1271,10 +1272,10 @@ hostname_match(const char *pattern, const char *actual_hostname) * Check to see if a connecting IP matches a given host name. */ static bool -check_hostname(POOL_CONNECTION *frontend, const char *hostname) +check_hostname(POOL_CONNECTION * frontend, const char *hostname) { struct addrinfo *gai_result, - *gai; + *gai; int ret; bool found; @@ -1288,14 +1289,14 @@ check_hostname(POOL_CONNECTION *frontend, const char *hostname) char remote_hostname[NI_MAXHOST]; ret = getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen, - remote_hostname, sizeof(remote_hostname), - NULL, 0, - NI_NAMEREQD); + remote_hostname, sizeof(remote_hostname), + NULL, 0, + NI_NAMEREQD); if (ret != 0) { /* remember failure; don't complain in the Pgpool-II log yet */ frontend->remote_hostname_resolv = -2; - //frontend->remote_hostname_errcode = ret; + /* frontend->remote_hostname_errcode = ret; */ return false; } @@ -1316,7 +1317,7 @@ check_hostname(POOL_CONNECTION *frontend, const char *hostname) { /* remember failure; don't complain in the postmaster log yet */ frontend->remote_hostname_resolv = -2; - //frontend->remote_hostname_errcode = ret; + /* frontend->remote_hostname_errcode = ret; */ return false; } @@ -1352,12 +1353,13 @@ check_hostname(POOL_CONNECTION *frontend, const char *hostname) if (!found) ereport(DEBUG2, (errmsg("pool_hba.conf host name \"%s\" rejected because address resolution did not return a match with IP address of client", - hostname))); + hostname))); frontend->remote_hostname_resolv = found ? +1 : -1; return found; } + /* * pg_foreach_ifaddr callback: does client addr match this machine interface? */ @@ -1406,6 +1408,7 @@ check_same_host_or_net(SockAddr *raddr, IPCompareMethod method) return cn.result; } + /* * Check to see if a connecting IP matches the given address and netmask. */ @@ -1414,8 +1417,8 @@ check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask) { if (raddr->addr.ss_family == addr->sa_family && rangeSockAddr(&raddr->addr, - (struct sockaddr_storage *) addr, - (struct sockaddr_storage *) mask)) + (struct sockaddr_storage *) addr, + (struct sockaddr_storage *) mask)) return true; return false; } @@ -1424,7 +1427,8 @@ check_ip(SockAddr *raddr, struct sockaddr *addr, struct sockaddr *mask) /* * Check comma user list for a specific user, handle group names. */ -static bool check_user(char *user, List *tokens) +static bool +check_user(char *user, List *tokens) { ListCell *cell; HbaToken *tok; @@ -1584,7 +1588,8 @@ tokenize_inc_file(List *tokens, * isblank() exists in the ISO C99 spec, but it's not very portable yet, * so provide our own version. */ -static bool pg_isblank(const char c) +static bool +pg_isblank(const char c) { return c == ' ' || c == '\t' || c == '\r'; } @@ -1885,8 +1890,9 @@ copy_hba_token(HbaToken *in) /* * PAM conversation function */ -static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, - struct pam_response ** resp, void *appdata_ptr) +static int +pam_passwd_conv_proc(int num_msg, const struct pam_message **msg, + struct pam_response **resp, void *appdata_ptr) { if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF) { @@ -1894,15 +1900,15 @@ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, { case PAM_ERROR_MSG: ereport(LOG, - (errmsg("PAM Error"), - errdetail("error from underlying PAM layer: %s", - msg[0]->msg))); + (errmsg("PAM Error"), + errdetail("error from underlying PAM layer: %s", + msg[0]->msg))); return PAM_CONV_ERR; default: ereport(LOG, - (errmsg("PAM Error"), - errdetail("unsupported PAM conversation %d/%s", - msg[0]->msg_style, msg[0]->msg))); + (errmsg("PAM Error"), + errdetail("unsupported PAM conversation %d/%s", + msg[0]->msg_style, msg[0]->msg))); return PAM_CONV_ERR; } } @@ -1910,30 +1916,30 @@ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, if (!appdata_ptr) { /* - * Workaround for Solaris 2.6 where the PAM library is broken and - * does not pass appdata_ptr to the conversation routine + * Workaround for Solaris 2.6 where the PAM library is broken and does + * not pass appdata_ptr to the conversation routine */ appdata_ptr = pam_passwd; } /* - * Password wasn't passed to PAM the first time around - let's go ask - * the client to send a password, which we then stuff into PAM. + * Password wasn't passed to PAM the first time around - let's go ask the + * client to send a password, which we then stuff into PAM. */ if (strlen(appdata_ptr) == 0) { - char *passwd; + char *passwd; sendAuthRequest(pam_frontend_kludge, AUTH_REQ_PASSWORD); passwd = recv_password_packet(pam_frontend_kludge); if (passwd == NULL) - return PAM_CONV_ERR; /* client didn't want to send password */ + return PAM_CONV_ERR; /* client didn't want to send password */ if (strlen(passwd) == 0) { ereport(LOG, - (errmsg("PAM Error"), + (errmsg("PAM Error"), errdetail("empty password returned by client"))); return PAM_CONV_ERR; } @@ -1941,10 +1947,9 @@ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, } /* - * PAM will free this memory in * pam_end() - * Do not use Palloc and freinds to allocate this memory, - * Since the PAM library will be freeing this memory who - * knowns nothing about our MemoryManager + * PAM will free this memory in * pam_end() Do not use Palloc and freinds + * to allocate this memory, Since the PAM library will be freeing this + * memory who knowns nothing about our MemoryManager */ *resp = calloc(num_msg, sizeof(struct pam_response)); @@ -1958,9 +1963,9 @@ static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, /* * Check authentication against PAM. */ -static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password) +static POOL_STATUS CheckPAMAuth(POOL_CONNECTION * frontend, char *user, char *password) { - int retval; + int retval; pam_handle_t *pamh = NULL; /* @@ -1974,7 +1979,7 @@ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *pas * later used inside the PAM conversation to pass the password to the * authentication module. */ - pam_passw_conv.appdata_ptr = (char *) password; /* from password above, + pam_passw_conv.appdata_ptr = (char *) password; /* from password above, * not allocated */ /* Optionally, one can set the service name in pool_hba.conf */ @@ -1988,78 +1993,79 @@ static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *pas if (retval != PAM_SUCCESS) { pam_passwd = NULL; /* Unset pam_passwd */ - ereport(FATAL, - (return_code(2), - errmsg("failed authentication against PAM"), - errdetail("unable to create PAM authenticator: %s", pam_strerror(pamh, retval)))); + ereport(FATAL, + (return_code(2), + errmsg("failed authentication against PAM"), + errdetail("unable to create PAM authenticator: %s", pam_strerror(pamh, retval)))); } retval = pam_set_item(pamh, PAM_USER, user); if (retval != PAM_SUCCESS) { pam_passwd = NULL; /* Unset pam_passwd */ - ereport(FATAL, - (return_code(2), - errmsg("failed authentication against PAM"), - errdetail("pam_set_item(PAM_USER) failed: %s", pam_strerror(pamh, retval)))); + ereport(FATAL, + (return_code(2), + errmsg("failed authentication against PAM"), + errdetail("pam_set_item(PAM_USER) failed: %s", pam_strerror(pamh, retval)))); } retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv); if (retval != PAM_SUCCESS) { pam_passwd = NULL; /* Unset pam_passwd */ - ereport(FATAL, - (return_code(2), - errmsg("failed authentication against PAM"), - errdetail("pam_set_item(PAM_CONV) failed: %s", pam_strerror(pamh, retval)))); + ereport(FATAL, + (return_code(2), + errmsg("failed authentication against PAM"), + errdetail("pam_set_item(PAM_CONV) failed: %s", pam_strerror(pamh, retval)))); } retval = pam_authenticate(pamh, 0); if (retval != PAM_SUCCESS) /* service name does not exist */ { pam_passwd = NULL; /* Unset pam_passwd */ - ereport(FATAL, - (return_code(2), - errmsg("failed authentication against PAM"), - errdetail("pam_authenticate failed: %s", pam_strerror(pamh, retval)))); + ereport(FATAL, + (return_code(2), + errmsg("failed authentication against PAM"), + errdetail("pam_authenticate failed: %s", pam_strerror(pamh, retval)))); } retval = pam_acct_mgmt(pamh, 0); if (retval != PAM_SUCCESS) { pam_passwd = NULL; /* Unset pam_passwd */ - ereport(FATAL, - (return_code(2), - errmsg("failed authentication against PAM"), - errdetail("system call pam_acct_mgmt failed : %s", pam_strerror(pamh, retval)))); + ereport(FATAL, + (return_code(2), + errmsg("failed authentication against PAM"), + errdetail("system call pam_acct_mgmt failed : %s", pam_strerror(pamh, retval)))); } retval = pam_end(pamh, retval); if (retval != PAM_SUCCESS) { - ereport(FATAL, - (return_code(2), - errmsg("failed authentication against PAM"), - errdetail("unable to release PAM authenticator: %s", pam_strerror(pamh, retval)))); -} + ereport(FATAL, + (return_code(2), + errmsg("failed authentication against PAM"), + errdetail("unable to release PAM authenticator: %s", pam_strerror(pamh, retval)))); + } pam_passwd = NULL; return POOL_CONTINUE; } -#endif /* USE_PAM */ +#endif /* USE_PAM */ static POOL_STATUS CheckUserExist(char *username) { - char *passwd; + char *passwd; /* Look for the entry in pool_passwd */ passwd = pool_get_passwd(username); if (passwd == NULL) return POOL_ERROR; + /* * Ok for now. Actual authentication will be performed later. */ diff --git a/src/auth/pool_passwd.c b/src/auth/pool_passwd.c index 051e756a7..68af68225 100644 --- a/src/auth/pool_passwd.c +++ b/src/auth/pool_passwd.c @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -39,7 +39,7 @@ static FILE *passwd_fd = NULL; /* File descriptor for pool_passwd */ -static char saved_passwd_filename[POOLMAXPATHLEN+1]; +static char saved_passwd_filename[POOLMAXPATHLEN + 1]; static POOL_PASSWD_MODE pool_passwd_mode; /* @@ -47,9 +47,10 @@ static POOL_PASSWD_MODE pool_passwd_mode; * If pool_passwd does not exist yet, create it. * Open pool_passwd. */ -void pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) +void +pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) { - char *openmode; + char *openmode; if (passwd_fd) return; @@ -58,7 +59,8 @@ void pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) if (saved_passwd_filename[0] == '\0') { - int len = strlen(pool_passwd_filename); + int len = strlen(pool_passwd_filename); + memcpy(saved_passwd_filename, pool_passwd_filename, len); saved_passwd_filename[len] = '\0'; } @@ -79,8 +81,8 @@ void pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) return; } ereport(ERROR, - (errmsg("initializing pool password, failed to open file:\"%s\"",pool_passwd_filename), - errdetail("file open failed with error:\"%s\"",strerror(errno)))); + (errmsg("initializing pool password, failed to open file:\"%s\"", pool_passwd_filename), + errdetail("file open failed with error:\"%s\"", strerror(errno)))); } } @@ -88,13 +90,14 @@ void pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode) * Update passwd. If the user does not exist, create a new entry. * Returns 0 on success non 0 otherwise. */ -int pool_create_passwdent(char *username, char *passwd) +int +pool_create_passwdent(char *username, char *passwd) { - int len; - int c; - char name[MAX_USER_NAME_LEN]; - char *p; - int readlen; + int len; + int c; + char name[MAX_USER_NAME_LEN]; + char *p; + int readlen; if (!passwd_fd) ereport(ERROR, @@ -107,7 +110,7 @@ int pool_create_passwdent(char *username, char *passwd) len = strlen(passwd); if (len <= 0) ereport(ERROR, - (errmsg("error updating password, invalid password length:%d",len))); + (errmsg("error updating password, invalid password length:%d", len))); rewind(passwd_fd); name[0] = '\0'; @@ -143,8 +146,8 @@ int pool_create_passwdent(char *username, char *passwd) else { /* Skip password */ - while((c = fgetc(passwd_fd)) != EOF && - c != '\n') + while ((c = fgetc(passwd_fd)) != EOF && + c != '\n') ; } } @@ -152,8 +155,7 @@ int pool_create_passwdent(char *username, char *passwd) fseek(passwd_fd, 0, SEEK_END); /* - * Not found the user name. - * Create a new entry. + * Not found the user name. Create a new entry. */ while ((c = *username++)) { @@ -174,13 +176,14 @@ int pool_create_passwdent(char *username, char *passwd) * entry does not exist or error occurred. * Returned password is on the static memory. */ -char *pool_get_passwd(char *username) +char * +pool_get_passwd(char *username) { - int c; - char name[MAX_USER_NAME_LEN+1]; - static char passwd[POOL_PASSWD_LEN+1]; - char *p; - int readlen; + int c; + char name[MAX_USER_NAME_LEN + 1]; + static char passwd[POOL_PASSWD_LEN + 1]; + char *p; + int readlen; if (!username) ereport(ERROR, @@ -198,7 +201,7 @@ char *pool_get_passwd(char *username) p = name; readlen = 0; - while (readlen < (sizeof(name)-1)) + while (readlen < (sizeof(name) - 1)) { c = fgetc(passwd_fd); if (c == EOF) @@ -217,8 +220,8 @@ char *pool_get_passwd(char *username) p = passwd; readlen = 0; - while((c = fgetc(passwd_fd)) != EOF && - c != '\n' && readlen < (sizeof(passwd)-1)) + while ((c = fgetc(passwd_fd)) != EOF && + c != '\n' && readlen < (sizeof(passwd) - 1)) { *p++ = c; readlen++; @@ -229,8 +232,8 @@ char *pool_get_passwd(char *username) else { /* Skip password */ - while((c = fgetc(passwd_fd)) != EOF && - c != '\n') + while ((c = fgetc(passwd_fd)) != EOF && + c != '\n') ; } } @@ -245,10 +248,11 @@ static char * getNextToken(char *buf, char **token) { #define MAX_TOKEN_LEN 128 - char *tbuf,*p; - bool bslash = false; - char tok[MAX_TOKEN_LEN+1]; - int readlen = 0; + char *tbuf, + *p; + bool bslash = false; + char tok[MAX_TOKEN_LEN + 1]; + int readlen = 0; *token = NULL; if (buf == NULL) @@ -267,20 +271,21 @@ getNextToken(char *buf, char **token) if (*tbuf == ':' && !bslash) { *p = '\0'; - if(readlen) + if (readlen) *token = pstrdup(tok); return tbuf + 1; } - /* just copy to the tok */ + /* just copy to the tok */ bslash = false; *p++ = *tbuf++; readlen++; } *p = '\0'; - if(readlen) + if (readlen) *token = pstrdup(tok); return NULL; } + /* * return the next token if the current token matches the * user @@ -288,9 +293,9 @@ getNextToken(char *buf, char **token) static char * userMatchesString(char *buf, char *user) { - char *tbuf, - *ttok; - bool bslash = false; + char *tbuf, + *ttok; + bool bslash = false; if (buf == NULL || user == NULL) return NULL; @@ -322,10 +327,11 @@ userMatchesString(char *buf, char *user) /* * user:passwod[:user:password] */ -PasswordMapping *pool_get_user_credentials(char *username) +PasswordMapping * +pool_get_user_credentials(char *username) { - PasswordMapping *pwdMapping = NULL; - char buf[1024]; + PasswordMapping *pwdMapping = NULL; + char buf[1024]; if (!username) ereport(ERROR, @@ -341,9 +347,9 @@ PasswordMapping *pool_get_user_credentials(char *username) while (!feof(passwd_fd) && !ferror(passwd_fd)) { - char *t = buf; - char *tok; - int len; + char *t = buf; + char *tok; + int len; if (fgets(buf, sizeof(buf), passwd_fd) == NULL) break; @@ -365,17 +371,18 @@ PasswordMapping *pool_get_user_credentials(char *username) pwdMapping = palloc0(sizeof(PasswordMapping)); pwdMapping->pgpoolUser.password = tok; pwdMapping->pgpoolUser.passwordType = get_password_type(pwdMapping->pgpoolUser.password); - pwdMapping->pgpoolUser.userName = (char*) pstrdup(username); + pwdMapping->pgpoolUser.userName = (char *) pstrdup(username); pwdMapping->mappedUser = false; } else continue; - /* Get backend user*/ + /* Get backend user */ t = getNextToken(t, &tok); if (tok) { /* check if we also have the password */ - char *pwd; + char *pwd; + t = getNextToken(t, &pwd); if (tok) { @@ -390,7 +397,8 @@ PasswordMapping *pool_get_user_credentials(char *username) return pwdMapping; } -void delete_passwordMapping(PasswordMapping *pwdMapping) +void +delete_passwordMapping(PasswordMapping * pwdMapping) { if (!pwdMapping) return; @@ -411,14 +419,16 @@ void delete_passwordMapping(PasswordMapping *pwdMapping) * Delete the entry by username. If specified entry does not exist, * does nothing. */ -void pool_delete_passwdent(char *username) +void +pool_delete_passwdent(char *username) { } /* * Finish this moil. Close pool_passwd. */ -void pool_finish_pool_passwd(void) +void +pool_finish_pool_passwd(void) { if (passwd_fd) { @@ -427,7 +437,8 @@ void pool_finish_pool_passwd(void) } } -void pool_reopen_passwd_file(void) +void +pool_reopen_passwd_file(void) { pool_finish_pool_passwd(); pool_init_pool_passwd(saved_passwd_filename, pool_passwd_mode); @@ -439,14 +450,16 @@ void pool_reopen_passwd_file(void) * for uset in pool_passwd file. * The returned password is always in plain text and palloc'd (if not null) */ -char *get_pgpool_config_user_password(char *username, char *password_in_config) +char * +get_pgpool_config_user_password(char *username, char *password_in_config) { PasswordType passwordType = PASSWORD_TYPE_UNKNOWN; - char *password = NULL; - PasswordMapping* password_mapping = NULL; + char *password = NULL; + PasswordMapping *password_mapping = NULL; + /* - * if the password specified in confg is empty strin or NULL - * look for the password in pool_passwd file + * if the password specified in confg is empty strin or NULL look for the + * password in pool_passwd file */ if (password_in_config == NULL || strlen(password_in_config) == 0) { @@ -467,22 +480,24 @@ char *get_pgpool_config_user_password(char *username, char *password_in_config) if (passwordType == PASSWORD_TYPE_AES) { /* - * decrypt the stored AES password - * for comparing it + * decrypt the stored AES password for comparing it */ password = get_decrypted_password(password); if (password == NULL) { ereport(WARNING, - (errmsg("could not get the password for user:%s",username), + (errmsg("could not get the password for user:%s", username), errdetail("unable to decrypt password from pool_passwd"), errhint("verify the valid pool_key exists"))); } else { delete_passwordMapping(password_mapping); - /* the password returned by get_decrypted_password() is - * already palloc'd */ + + /* + * the password returned by get_decrypted_password() is already + * palloc'd + */ return password; } } @@ -490,12 +505,12 @@ char *get_pgpool_config_user_password(char *username, char *password_in_config) if (passwordType != PASSWORD_TYPE_PLAINTEXT) { ereport(WARNING, - (errmsg("could not get the password for user:%s",username), - errdetail("username \"%s\" has invalid password type",username))); + (errmsg("could not get the password for user:%s", username), + errdetail("username \"%s\" has invalid password type", username))); password = NULL; } if (password) - password = (char*)pstrdup(password); + password = (char *) pstrdup(password); delete_passwordMapping(password_mapping); @@ -503,44 +518,46 @@ char *get_pgpool_config_user_password(char *username, char *password_in_config) } #ifndef POOL_PRIVATE -char *get_decrypted_password(const char *shadow_pass) +char * +get_decrypted_password(const char *shadow_pass) { if (get_password_type(shadow_pass) == PASSWORD_TYPE_AES) { - unsigned char b64_dec[MAX_PGPASS_LEN *2]; + unsigned char b64_dec[MAX_PGPASS_LEN * 2]; unsigned char plaintext[MAX_PGPASS_LEN]; - int len; - char *pwd; - const char *enc_key = (const char*)get_pool_key(); + int len; + char *pwd; + const char *enc_key = (const char *) get_pool_key(); if (enc_key == NULL) return NULL; - pwd = (char*)shadow_pass + 3; + pwd = (char *) shadow_pass + 3; if ((len = strlen(pwd)) == 0) return NULL; - if ((len = pg_b64_decode((const char*)pwd, len, (char*)b64_dec)) == 0) + if ((len = pg_b64_decode((const char *) pwd, len, (char *) b64_dec)) == 0) { ereport(WARNING, (errmsg("base64 decoding failed"))); return NULL; } if ((len = aes_decrypt_with_password(b64_dec, len, - enc_key, plaintext)) <= 0) + enc_key, plaintext)) <= 0) { ereport(WARNING, (errmsg("decryption failed"))); return NULL; } plaintext[len] = 0; - return pstrdup((const char*)plaintext); + return pstrdup((const char *) plaintext); } return NULL; } #else -char *get_decrypted_password(const char *shadow_pass) +char * +get_decrypted_password(const char *shadow_pass) { ereport(ERROR, (errmsg("unable to decrypt password"))); @@ -552,11 +569,11 @@ get_password_type(const char *shadow_pass) { if (strncmp(shadow_pass, PASSWORD_MD5_PREFIX, strlen(PASSWORD_MD5_PREFIX)) == 0) { - if ( strlen(shadow_pass) == MD5_PASSWD_LEN + strlen(PASSWORD_MD5_PREFIX)) + if (strlen(shadow_pass) == MD5_PASSWD_LEN + strlen(PASSWORD_MD5_PREFIX)) return PASSWORD_TYPE_MD5; return PASSWORD_TYPE_PLAINTEXT; } - if (strncmp(shadow_pass, PASSWORD_AES_PREFIX, strlen(PASSWORD_AES_PREFIX)) == 0 ) + if (strncmp(shadow_pass, PASSWORD_AES_PREFIX, strlen(PASSWORD_AES_PREFIX)) == 0) return PASSWORD_TYPE_AES; if (strncmp(shadow_pass, PASSWORD_SCRAM_PREFIX, strlen(PASSWORD_SCRAM_PREFIX)) == 0) return PASSWORD_TYPE_SCRAM_SHA_256; @@ -568,14 +585,15 @@ get_password_type(const char *shadow_pass) * Get a key from the pgpool key file. return the palloc'd. * value */ -char *read_pool_key(char *key_file_path) +char * +read_pool_key(char *key_file_path) { - FILE *fp; + FILE *fp; struct stat stat_buf; - char *key = NULL; + char *key = NULL; #define LINELEN MAX_POOL_KEY_LEN - char buf[LINELEN]; + char buf[LINELEN]; if (strlen(key_file_path) == 0) return NULL; @@ -587,7 +605,7 @@ char *read_pool_key(char *key_file_path) if (!S_ISREG(stat_buf.st_mode)) { ereport(WARNING, - (errmsg("pool key file \"%s\" is not a text file\n",key_file_path))); + (errmsg("pool key file \"%s\" is not a text file\n", key_file_path))); return NULL; } @@ -595,13 +613,13 @@ char *read_pool_key(char *key_file_path) if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) { ereport(WARNING, - (errmsg("pool key file \"%s\" is not a text file\n",key_file_path))); + (errmsg("pool key file \"%s\" is not a text file\n", key_file_path))); ereport(WARNING, (errmsg("pool key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n", - key_file_path))); - /* do we want to allow unsecure pool key file ?*/ - //return NULL; + key_file_path))); + /* do we want to allow unsecure pool key file ? */ + /* return NULL; */ } fp = fopen(key_file_path, "r"); @@ -610,7 +628,7 @@ char *read_pool_key(char *key_file_path) while (!feof(fp) && !ferror(fp)) { - int len; + int len; if (fgets(buf, sizeof(buf), fp) == NULL) break; diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c index a90d784c5..4559c61c0 100644 --- a/src/config/pool_config_variables.c +++ b/src/config/pool_config_variables.c @@ -41,10 +41,10 @@ extern POOL_CONFIG g_pool_config; struct config_generic **all_parameters = NULL; -static int num_all_parameters = 0; +static int num_all_parameters = 0; -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 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 void build_variable_groups(void); static void build_config_variables(void); @@ -55,82 +55,82 @@ static struct config_generic *find_option(const char *name, int elevel); static bool config_post_processor(ConfigContext context, int elevel); static void sort_config_vars(void); -static bool -setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const char* name, +static bool setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const char *name, const char *value, ConfigContext context, int elevel); static bool setConfigOption(const char *name, const char *value, - ConfigContext context, GucSource source, int elevel); + ConfigContext context, GucSource source, int elevel); static bool setConfigOptionVar(struct config_generic *record, const char *name, int index_val, - const char *value, ConfigContext context, GucSource source, int elevel); + const char *value, ConfigContext context, GucSource source, int elevel); -static bool get_index_in_var_name(struct config_generic* record, - const char* name, int *index, int elevel); +static bool get_index_in_var_name(struct config_generic *record, + const char *name, int *index, int elevel); -static bool MakeDBRedirectListRegex (char* newval, int elevel); -static bool MakeAppRedirectListRegex (char* newval, int elevel); +static bool MakeDBRedirectListRegex(char *newval, int elevel); +static bool MakeAppRedirectListRegex(char *newval, int elevel); static bool check_redirect_node_spec(char *node_spec); static char **get_list_from_string(const char *str, const char *delimi, int *n); static char **get_list_from_string_regex_delim(const char *str, const char *delimi, int *n); /*show functions */ -static const char* IntValueShowFunc(int value); -static const char* HBDestinationPortShowFunc(int index); -static const char* HBDestinationShowFunc(int index); -static const char* HBDeviceShowFunc(int index); -static const char* OtherWDPortShowFunc(int index); -static const char* OtherPPPortShowFunc(int index); -static const char* OtherPPHostShowFunc(int index); -static const char* BackendFlagsShowFunc(int index); -static const char* BackendDataDirShowFunc(int index); -static const char* BackendHostShowFunc(int index); -static const char* BackendPortShowFunc(int index); -static const char* BackendWeightShowFunc(int index); - -static const char* HealthCheckPeriodShowFunc(int index); -static const char* HealthCheckTimeOutShowFunc(int index); -static const char* HealthCheckMaxRetriesShowFunc(int index); -static const char* HealthCheckRetryDelayShowFunc(int index); -static const char* HealthCheckConnectTimeOutShowFunc(int index); -static const char* HealthCheckUserShowFunc(int index); -static const char* HealthCheckPasswordShowFunc(int index); -static const char* HealthCheckDatabaseShowFunc(int index); +static const char *IntValueShowFunc(int value); +static const char *HBDestinationPortShowFunc(int index); +static const char *HBDestinationShowFunc(int index); +static const char *HBDeviceShowFunc(int index); +static const char *OtherWDPortShowFunc(int index); +static const char *OtherPPPortShowFunc(int index); +static const char *OtherPPHostShowFunc(int index); +static const char *BackendFlagsShowFunc(int index); +static const char *BackendDataDirShowFunc(int index); +static const char *BackendHostShowFunc(int index); +static const char *BackendPortShowFunc(int index); +static const char *BackendWeightShowFunc(int index); + +static const char *HealthCheckPeriodShowFunc(int index); +static const char *HealthCheckTimeOutShowFunc(int index); +static const char *HealthCheckMaxRetriesShowFunc(int index); +static const char *HealthCheckRetryDelayShowFunc(int index); +static const char *HealthCheckConnectTimeOutShowFunc(int index); +static const char *HealthCheckUserShowFunc(int index); +static const char *HealthCheckPasswordShowFunc(int index); +static const char *HealthCheckDatabaseShowFunc(int index); /* check empty slot functions */ static bool WdIFSlotEmptyCheckFunc(int index); static bool WdSlotEmptyCheckFunc(int index); static bool BackendSlotEmptyCheckFunc(int index); + /*variable custom assign functions */ -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 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 HealthCheckPeriodAssignFunc (ConfigContext context, int newval, int index, int elevel); -static bool HealthCheckTimeOutAssignFunc (ConfigContext context, int newval, int index, int elevel); -static bool HealthCheckMaxRetriesAssignFunc (ConfigContext context, int newval, int index, int elevel); -static bool HealthCheckRetryDelayAssignFunc (ConfigContext context, int newval, int index, int elevel); -static bool HealthCheckConnectTimeOutAssignFunc (ConfigContext context, int newval, int index, int elevel); - -static bool HealthCheckUserAssignFunc(ConfigContext context, char* newval, int index, int elevel); -static bool HealthCheckPasswordAssignFunc(ConfigContext context, char* newval, int index, int elevel); -static bool HealthCheckDatabaseAssignFunc(ConfigContext context, char* newval, int index, int elevel); - -static bool LogDestinationProcessFunc (char* newval, int elevel); -static bool SyslogIdentProcessFunc (char* newval, int elevel); -static bool SyslogFacilityProcessFunc (int newval, int elevel); - -static struct config_generic* get_index_free_record_if_any(struct config_generic* record); +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 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 HealthCheckPeriodAssignFunc(ConfigContext context, int newval, int index, int elevel); +static bool HealthCheckTimeOutAssignFunc(ConfigContext context, int newval, int index, int elevel); +static bool HealthCheckMaxRetriesAssignFunc(ConfigContext context, int newval, int index, int elevel); +static bool HealthCheckRetryDelayAssignFunc(ConfigContext context, int newval, int index, int elevel); +static bool HealthCheckConnectTimeOutAssignFunc(ConfigContext context, int newval, int index, int elevel); + +static bool HealthCheckUserAssignFunc(ConfigContext context, char *newval, int index, int elevel); +static bool HealthCheckPasswordAssignFunc(ConfigContext context, char *newval, int index, int elevel); +static bool HealthCheckDatabaseAssignFunc(ConfigContext context, char *newval, int index, int elevel); + +static bool LogDestinationProcessFunc(char *newval, int elevel); +static bool SyslogIdentProcessFunc(char *newval, int elevel); +static bool SyslogFacilityProcessFunc(int newval, int elevel); + +static struct config_generic *get_index_free_record_if_any(struct config_generic *record); #ifndef POOL_PRIVATE @@ -140,17 +140,17 @@ static struct config_generic* get_index_free_record_if_any(struct config_generic * not present for tools. */ -static const char* config_enum_lookup_by_value(struct config_enum * record, int val); +static const char *config_enum_lookup_by_value(struct config_enum *record, int val); -static char *ShowOption(struct config_generic * record, int index, int elevel); +static char *ShowOption(struct config_generic *record, int index, int elevel); -static char *config_enum_get_options(struct config_enum * record, const char *prefix, +static char *config_enum_get_options(struct config_enum *record, const char *prefix, const char *suffix, const char *separator); -static void send_row_description_for_detail_view(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -static int send_grouped_type_variable_to_frontend(struct config_grouped_array_var* grouped_record, - POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -static int send_array_type_variable_to_frontend(struct config_generic* record, - POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static void send_row_description_for_detail_view(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +static int send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_record, + POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +static int send_array_type_variable_to_frontend(struct config_generic *record, + POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); #endif @@ -232,298 +232,298 @@ 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, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.serialize_accept, /* variable */ - false, /* boot value */ - NULL, /* assign func */ - NULL, /* check func */ - NULL /* show hook */ + false, /* boot value */ + NULL, /* assign func */ + NULL, /* check func */ + NULL /* show hook */ }, { {"failover_when_quorum_exists", CFGCXT_INIT, FAILOVER_CONFIG, "Do failover only when cluster has the quorum.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.failover_when_quorum_exists, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"failover_require_consensus", CFGCXT_INIT, FAILOVER_CONFIG, "Only do failover when majority aggrees.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.failover_require_consensus, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"allow_multiple_failover_requests_from_node", CFGCXT_INIT, FAILOVER_CONFIG, "A Pgpool-II node can send multiple failover requests to build consensus.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.allow_multiple_failover_requests_from_node, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"log_connections", CFGCXT_RELOAD, LOGING_CONFIG, "Logs each successful connection.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.log_connections, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"log_hostname", CFGCXT_RELOAD, LOGING_CONFIG, "Logs the host name in the connection logs.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.log_hostname, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"enable_pool_hba", CFGCXT_RELOAD, CONNECTION_CONFIG, "Use pool_hba.conf for client authentication.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.enable_pool_hba, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"replication_mode", CFGCXT_INIT, LOGING_CONFIG, "Enables replication mode.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.replication_mode, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"load_balance_mode", CFGCXT_INIT, LOAD_BALANCE_CONFIG, "Enables load balancing of queries.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.load_balance_mode, false, - NULL, NULL,NULL + 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,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.replication_stop_on_mismatch, false, - NULL, NULL,NULL + 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,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.failover_if_affected_tuples_mismatch, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"replicate_select", CFGCXT_RELOAD, REPLICATION_CONFIG, "Replicate SELECT statements when load balancing is disabled.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.replicate_select, false, - NULL, NULL,NULL + NULL, NULL, NULL }, - + { {"master_slave_mode", CFGCXT_INIT, MASTER_SLAVE_CONFIG, "Enables Master/Slave mode.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.master_slave_mode, false, - NULL, NULL,NULL + NULL, NULL, NULL }, - + { {"connection_cache", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "Caches connections to backends.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.connection_cache, true, - NULL, NULL,NULL + 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,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.fail_over_on_backend_error, true, - NULL, NULL,NULL + NULL, NULL, NULL }, - + { {"detach_false_primary", CFGCXT_RELOAD, FAILOVER_CONFIG, "Automatically detaches false primary node.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.detach_false_primary, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"insert_lock", CFGCXT_RELOAD, REPLICATION_CONFIG, "Automatically locks table with INSERT to keep SERIAL data consistency", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.insert_lock, true, - NULL, NULL,NULL + NULL, NULL, NULL }, - + { {"ignore_leading_white_space", CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, "Ignores leading white spaces of each query string.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.ignore_leading_white_space, true, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"log_statement", CFGCXT_SESSION, LOGING_CONFIG, "Logs all statements in the pgpool logs.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.log_statement, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"log_per_node_statement", CFGCXT_SESSION, LOGING_CONFIG, "Logs per node detailed SQL statements.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.log_per_node_statement, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"log_client_messages", CFGCXT_SESSION, LOGING_CONFIG, "Logs any client messages in the pgpool logs.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.log_client_messages, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"use_watchdog", CFGCXT_INIT, WATCHDOG_CONFIG, "Enables the pgpool-II watchdog.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.use_watchdog, false, - NULL, NULL,NULL + 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,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.clear_memqcache_on_escalation, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"ssl", CFGCXT_INIT, SSL_CONFIG, "Enables SSL support for frontend and backend connections", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.ssl, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"check_temp_table", CFGCXT_SESSION, GENERAL_CONFIG, "Enables temporary table check.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.check_temp_table, true, - NULL, NULL,NULL + NULL, NULL, NULL }, - + { {"check_unlogged_table", CFGCXT_SESSION, GENERAL_CONFIG, "Enables unlogged table check.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.check_unlogged_table, true, - NULL, NULL,NULL + NULL, NULL, NULL }, - + { {"memory_cache_enabled", CFGCXT_RELOAD, CACHE_CONFIG, "Enables the memory cache functionality.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.memory_cache_enabled, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"memqcache_auto_cache_invalidation", CFGCXT_RELOAD, CACHE_CONFIG, "Automatically deletes the cache related to the updated tables.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.memqcache_auto_cache_invalidation, true, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"allow_sql_comments", CFGCXT_SESSION, LOAD_BALANCE_CONFIG, "Ignore SQL comments, while judging if load balance or query cache is possible.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.allow_sql_comments, false, - NULL, NULL,NULL + NULL, NULL, NULL }, { {"allow_clear_text_frontend_auth", CFGCXT_RELOAD, GENERAL_CONFIG, "allow to use clear text password authentication with clients, when pool_passwd does not contain the user password.", - CONFIG_VAR_TYPE_BOOL,false, 0 + CONFIG_VAR_TYPE_BOOL, false, 0 }, &g_pool_config.allow_clear_text_frontend_auth, false, - NULL, NULL,NULL + NULL, NULL, NULL }, /* End-of-list marker */ @@ -536,31 +536,31 @@ static struct config_string ConfigureNamesString[] = { {"database_redirect_preference_list", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, "redirect by database name.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, - &g_pool_config.database_redirect_preference_list, /* variable */ - NULL,/* boot value */ - NULL,/* assign_func */ - NULL,/* check_func */ - MakeDBRedirectListRegex, /* process func */ - NULL /* show hook */ + &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.app_name_redirect_preference_list, NULL, - NULL,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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.listen_addresses, "localhost", @@ -570,17 +570,17 @@ static struct config_string ConfigureNamesString[] = { {"pcp_listen_addresses", CFGCXT_INIT, CONNECTION_CONFIG, "hostname(s) or IP address(es) on which pcp will listen on.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.socket_dir, DEFAULT_SOCKET_DIR, @@ -590,7 +590,7 @@ static struct config_string ConfigureNamesString[] = { {"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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.pcp_socket_dir, DEFAULT_SOCKET_DIR, @@ -599,8 +599,8 @@ static struct config_string ConfigureNamesString[] = { {"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, 0 + "The directory to create the UNIX domain socket for accepting pgpool-II watchdog IPC connections.", + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_ipc_socket_dir, DEFAULT_SOCKET_DIR, @@ -610,7 +610,7 @@ static struct config_string ConfigureNamesString[] = { {"log_destination", CFGCXT_RELOAD, LOGING_CONFIG, "destination of pgpool-II log", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.log_destination_str, "stderr", @@ -622,7 +622,7 @@ static struct config_string ConfigureNamesString[] = { {"syslog_ident", CFGCXT_RELOAD, LOGING_CONFIG, "syslog program ident string.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.syslog_ident, "pgpool", @@ -634,7 +634,7 @@ static struct config_string ConfigureNamesString[] = { {"pid_file_name", CFGCXT_INIT, FILE_LOCATION_CONFIG, "Path to store pgpool-II pid file.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.pid_file_name, DEFAULT_PID_FILE_NAME, @@ -644,7 +644,7 @@ static struct config_string ConfigureNamesString[] = { {"pool_passwd", CFGCXT_INIT, FILE_LOCATION_CONFIG, "File name of pool_passwd for md5 authentication.", - CONFIG_VAR_TYPE_STRING,false, VAR_HIDDEN_VALUE + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_VALUE }, &g_pool_config.pool_passwd, "pool_passwd", @@ -654,7 +654,7 @@ static struct config_string ConfigureNamesString[] = { {"log_line_prefix", CFGCXT_RELOAD, LOGING_CONFIG, "printf-style string to output at beginning of each log line.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.log_line_prefix, "%t: pid %p: ", @@ -664,107 +664,107 @@ static struct config_string ConfigureNamesString[] = { {"sr_check_user", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, "The User name to perform streaming replication delay check.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, VAR_HIDDEN_VALUE + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_VALUE }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.recovery_user, "", NULL, NULL, NULL, NULL }, - + { {"recovery_password", CFGCXT_RELOAD, RECOVERY_CONFIG, "Password for online recovery.", - CONFIG_VAR_TYPE_STRING,false, VAR_HIDDEN_VALUE + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_VALUE }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.lobj_lock_table, "", @@ -774,37 +774,37 @@ static struct config_string ConfigureNamesString[] = { {"wd_escalation_command", CFGCXT_RELOAD, WATCHDOG_CONFIG, "Command to execute when watchdog node becomes cluster master/leader node.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.delegate_IP, "", @@ -814,7 +814,7 @@ static struct config_string ConfigureNamesString[] = { {"wd_hostname", CFGCXT_INIT, WATCHDOG_CONFIG, "Host name or IP address of this watchdog.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_hostname, "", @@ -824,17 +824,17 @@ static struct config_string ConfigureNamesString[] = { {"ping_path", CFGCXT_INIT, WATCHDOG_CONFIG, "path to ping command.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.if_cmd_path, "/sbin", @@ -844,17 +844,17 @@ static struct config_string ConfigureNamesString[] = { {"if_up_cmd", CFGCXT_INIT, WATCHDOG_CONFIG, "Complete command to bring UP virtual interface.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.if_down_cmd, "ip addr del $_IP_$/24 dev eth0", @@ -864,7 +864,7 @@ static struct config_string ConfigureNamesString[] = { {"arping_path", CFGCXT_INIT, WATCHDOG_CONFIG, "path to arping command.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.arping_path, "/usr/sbin", @@ -874,7 +874,7 @@ static struct config_string ConfigureNamesString[] = { {"arping_cmd", CFGCXT_INIT, WATCHDOG_CONFIG, "arping command.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.arping_cmd, "arping -U $_IP_$ -w 1", @@ -884,7 +884,7 @@ static struct config_string ConfigureNamesString[] = { {"wd_lifecheck_query", CFGCXT_INIT, WATCHDOG_CONFIG, "SQL query to be used by watchdog lifecheck.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_lifecheck_query, "SELECT 1", @@ -894,7 +894,7 @@ static struct config_string ConfigureNamesString[] = { {"wd_lifecheck_dbname", CFGCXT_RELOAD, WATCHDOG_CONFIG, "Database name to be used for by watchdog lifecheck.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_lifecheck_dbname, "postgres", @@ -904,27 +904,27 @@ static struct config_string ConfigureNamesString[] = { {"wd_lifecheck_user", CFGCXT_RELOAD, WATCHDOG_CONFIG, "User name to be used for by watchdog lifecheck.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, VAR_HIDDEN_VALUE + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_VALUE }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_authkey, "", @@ -934,37 +934,37 @@ static struct config_string ConfigureNamesString[] = { {"ssl_cert", CFGCXT_INIT, SSL_CONFIG, "Path to the SSL public certificate file.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.ssl_ca_cert_dir, "", @@ -974,7 +974,7 @@ static struct config_string ConfigureNamesString[] = { {"memqcache_oiddir", CFGCXT_INIT, CACHE_CONFIG, "Tempory directory to record table oids.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.memqcache_oiddir, "/var/log/pgpool/oiddir", @@ -984,17 +984,17 @@ static struct config_string ConfigureNamesString[] = { {"memqcache_memcached_host", CFGCXT_INIT, CACHE_CONFIG, "Hostname or IP address of memcached.", - CONFIG_VAR_TYPE_STRING,false, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.logdir, DEFAULT_LOGDIR, @@ -1010,20 +1010,20 @@ 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, 0 + CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, - &g_pool_config.reset_query_list, /* variable */ - &g_pool_config.num_reset_queries, /* item count var */ - (const char*)default_reset_query_list, /* boot value */ - ";",/* token seperator */ - false, /* compute_regex ?*/ - NULL, NULL, NULL /* assign, check, show funcs */ + &g_pool_config.reset_query_list, /* variable */ + &g_pool_config.num_reset_queries, /* item count var */ + (const char *) default_reset_query_list, /* boot value */ + ";", /* token seperator */ + 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, 0 + CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, &g_pool_config.white_function_list, &g_pool_config.num_white_function_list, @@ -1036,11 +1036,11 @@ static struct config_string_list ConfigureNamesStringList[] = { {"black_function_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, "list of functions that writes to database.", - CONFIG_VAR_TYPE_STRING_LIST,false, 0 + CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, &g_pool_config.black_function_list, &g_pool_config.num_black_function_list, - (const char*)default_black_function_list, + (const char *) default_black_function_list, ",", true, NULL, NULL, NULL @@ -1048,7 +1048,7 @@ static struct config_string_list ConfigureNamesStringList[] = { {"white_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG, "list of tables to be cached.", - CONFIG_VAR_TYPE_STRING_LIST,false, 0 + CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, &g_pool_config.white_memqcache_table_list, &g_pool_config.num_white_memqcache_table_list, @@ -1061,7 +1061,7 @@ static struct config_string_list ConfigureNamesStringList[] = { {"black_memqcache_table_list", CFGCXT_RELOAD, CACHE_CONFIG, "list of tables should not be cached.", - CONFIG_VAR_TYPE_STRING_LIST,false, 0 + CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, &g_pool_config.black_memqcache_table_list, &g_pool_config.num_black_memqcache_table_list, @@ -1074,7 +1074,7 @@ static struct config_string_list ConfigureNamesStringList[] = { {"black_query_pattern_list", CFGCXT_RELOAD, CONNECTION_POOL_CONFIG, "list of query patterns that should be sent to primary node.", - CONFIG_VAR_TYPE_STRING_LIST,false, 0 + CONFIG_VAR_TYPE_STRING_LIST, false, 0 }, &g_pool_config.black_query_pattern_list, &g_pool_config.num_black_query_pattern_list, @@ -1087,7 +1087,7 @@ static struct config_string_list ConfigureNamesStringList[] = { {"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, 0 + CONFIG_VAR_TYPE_STRING, false, 0 }, &g_pool_config.wd_monitoring_interfaces_list, &g_pool_config.num_wd_monitoring_interfaces_list, @@ -1107,33 +1107,33 @@ static struct config_long ConfigureNamesLong[] = { {"delay_threshold", CFGCXT_RELOAD, STREAMING_REPLICATION_CONFIG, "standby delay threshold.", - CONFIG_VAR_TYPE_LONG,false, 0 + CONFIG_VAR_TYPE_LONG, false, 0 }, &g_pool_config.delay_threshold, 0, - 0,LONG_MAX, + 0, LONG_MAX, NULL, NULL, NULL }, { {"relcache_expire", CFGCXT_INIT, CACHE_CONFIG, - "Relation cache expiration time in seconds.", - CONFIG_VAR_TYPE_LONG,false, 0 + "Relation cache expiration time in seconds.", + CONFIG_VAR_TYPE_LONG, false, 0 }, &g_pool_config.relcache_expire, 0, - 0,LONG_MAX, + 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, 0 + CONFIG_VAR_TYPE_LONG, false, 0 }, &g_pool_config.memqcache_total_size, - (int64)67108864, - 0,LONG_MAX, + (int64) 67108864, + 0, LONG_MAX, NULL, NULL, NULL }, @@ -1148,11 +1148,11 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"backend_port", CFGCXT_RELOAD, CONNECTION_CONFIG, "port number of PostgreSQL backend.", - CONFIG_VAR_TYPE_INT_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 0, - 1024,65535, + 1024, 65535, EMPTY_CONFIG_INT, BackendPortAssignFunc, NULL, BackendPortShowFunc, BackendSlotEmptyCheckFunc }, @@ -1160,11 +1160,11 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"heartbeat_destination_port", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, "Destination port for sending heartbeat.", - CONFIG_VAR_TYPE_INT_ARRAY,true, 0, WD_MAX_IF_NUM + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, WD_MAX_IF_NUM }, NULL, 0, - 1024,65535, + 1024, 65535, EMPTY_CONFIG_INT, HBDestinationPortAssignFunc, NULL, HBDestinationPortShowFunc, WdIFSlotEmptyCheckFunc }, @@ -1172,130 +1172,130 @@ static struct config_int_array ConfigureNamesIntArray[] = { {"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, 0, MAX_WATCHDOG_NUM + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_WATCHDOG_NUM }, NULL, 0, - 1024,65535, + 1024, 65535, EMPTY_CONFIG_INT, - OtherWDPortAssignFunc, NULL, OtherWDPortShowFunc,WdSlotEmptyCheckFunc + OtherWDPortAssignFunc, NULL, OtherWDPortShowFunc, WdSlotEmptyCheckFunc }, { {"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, 0, MAX_WATCHDOG_NUM + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_WATCHDOG_NUM }, NULL, 0, - 1024,65535, + 1024, 65535, EMPTY_CONFIG_INT, - OtherPPPortAssignFunc, NULL, OtherPPPortShowFunc,WdSlotEmptyCheckFunc + OtherPPPortAssignFunc, NULL, OtherPPPortShowFunc, WdSlotEmptyCheckFunc }, { {"health_check_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Backend node health check timeout value in seconds.", - CONFIG_VAR_TYPE_INT_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 20, - 0,INT_MAX, + 0, INT_MAX, { {"health_check_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default health check timeout value for node for which health_check_timeout[node-id] is not specified.", - CONFIG_VAR_TYPE_INT,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_INT, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_timeout, 20, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - HealthCheckTimeOutAssignFunc, NULL, HealthCheckTimeOutShowFunc,BackendSlotEmptyCheckFunc + HealthCheckTimeOutAssignFunc, NULL, HealthCheckTimeOutShowFunc, BackendSlotEmptyCheckFunc }, { {"health_check_period", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Time interval in seconds between the health checks.", - CONFIG_VAR_TYPE_INT_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 0, - 0,INT_MAX, + 0, INT_MAX, { {"health_check_period", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default time interval between health checks for node for which health_check_period[node-id] is not specified.", - CONFIG_VAR_TYPE_INT,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_INT, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_period, 0, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - HealthCheckPeriodAssignFunc, NULL, HealthCheckPeriodShowFunc,BackendSlotEmptyCheckFunc + HealthCheckPeriodAssignFunc, NULL, HealthCheckPeriodShowFunc, BackendSlotEmptyCheckFunc }, { {"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_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 0, - 0,INT_MAX, + 0, INT_MAX, { {"health_check_max_retries", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default maximum number of retries for node for which health_check_max_retries[node-id] is not specified.", - CONFIG_VAR_TYPE_INT,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_INT, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_max_retries, 0, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - HealthCheckMaxRetriesAssignFunc, NULL, HealthCheckMaxRetriesShowFunc,BackendSlotEmptyCheckFunc + HealthCheckMaxRetriesAssignFunc, NULL, HealthCheckMaxRetriesShowFunc, BackendSlotEmptyCheckFunc }, { {"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_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 1, - 0,INT_MAX, + 0, INT_MAX, { {"health_check_retry_delay", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default time between failed health check retries for node for which health_check_retry_delay[node-id] is not specified.", - CONFIG_VAR_TYPE_INT,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_INT, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_retry_delay, 1, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - HealthCheckRetryDelayAssignFunc, NULL, HealthCheckRetryDelayShowFunc,BackendSlotEmptyCheckFunc + HealthCheckRetryDelayAssignFunc, NULL, HealthCheckRetryDelayShowFunc, BackendSlotEmptyCheckFunc }, { {"connect_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Timeout in milliseconds before giving up connecting to backend.", - CONFIG_VAR_TYPE_INT_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_INT_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 10000, - 0,INT_MAX, + 0, INT_MAX, { {"connect_timeout", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default connect_timeout value for node for which connect_timeout[node-id] is not specified.", - CONFIG_VAR_TYPE_INT,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_INT, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.connect_timeout, 10000, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - HealthCheckConnectTimeOutAssignFunc, NULL, HealthCheckConnectTimeOutShowFunc,BackendSlotEmptyCheckFunc + HealthCheckConnectTimeOutAssignFunc, NULL, HealthCheckConnectTimeOutShowFunc, BackendSlotEmptyCheckFunc }, /* End-of-list marker */ EMPTY_CONFIG_INT_ARRAY @@ -1315,15 +1315,15 @@ static struct config_double_array ConfigureNamesDoubleArray[] = { {"backend_weight", CFGCXT_RELOAD, CONNECTION_CONFIG, "load balance weight of backend.", - CONFIG_VAR_TYPE_DOUBLE_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_DOUBLE_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, 0, - 0.0,100000000.0, + 0.0, 100000000.0, EMPTY_CONFIG_DOUBLE, - BackendWeightAssignFunc, NULL, BackendWeightShowFunc,BackendSlotEmptyCheckFunc + BackendWeightAssignFunc, NULL, BackendWeightShowFunc, BackendSlotEmptyCheckFunc }, - + /* End-of-list marker */ EMPTY_CONFIG_DOUBLE_ARRAY }; @@ -1334,91 +1334,91 @@ 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, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, "", EMPTY_CONFIG_STRING, - BackendHostAssignFunc, NULL, BackendHostShowFunc,BackendSlotEmptyCheckFunc + BackendHostAssignFunc, NULL, BackendHostShowFunc, BackendSlotEmptyCheckFunc }, { {"backend_data_directory", CFGCXT_RELOAD, CONNECTION_CONFIG, "data directory of the backend.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, "", EMPTY_CONFIG_STRING, - BackendDataDirAssignFunc, NULL, BackendDataDirShowFunc,BackendSlotEmptyCheckFunc + BackendDataDirAssignFunc, NULL, BackendDataDirShowFunc, BackendSlotEmptyCheckFunc }, - + { {"backend_flag", CFGCXT_RELOAD, CONNECTION_CONFIG, "Controls various backend behavior.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, "ALLOW_TO_FAILOVER", EMPTY_CONFIG_STRING, - BackendFlagsAssignFunc, NULL, BackendFlagsShowFunc,BackendSlotEmptyCheckFunc + BackendFlagsAssignFunc, NULL, BackendFlagsShowFunc, BackendSlotEmptyCheckFunc }, { {"backend_flag", CFGCXT_RELOAD, CONNECTION_CONFIG, "Controls various backend behavior.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, "ALWAYS_MASTER", EMPTY_CONFIG_STRING, - BackendFlagsAssignFunc, NULL, BackendFlagsShowFunc,BackendSlotEmptyCheckFunc + BackendFlagsAssignFunc, NULL, BackendFlagsShowFunc, BackendSlotEmptyCheckFunc }, { {"heartbeat_destination", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, "destination host for sending heartbeat signal.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, WD_MAX_IF_NUM + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, WD_MAX_IF_NUM }, NULL, "", EMPTY_CONFIG_STRING, - HBDestinationAssignFunc, NULL, HBDestinationShowFunc,WdIFSlotEmptyCheckFunc + HBDestinationAssignFunc, NULL, HBDestinationShowFunc, WdIFSlotEmptyCheckFunc }, { {"heartbeat_device", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, "Name of NIC device for sending hearbeat.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, WD_MAX_IF_NUM + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, WD_MAX_IF_NUM }, NULL, "", EMPTY_CONFIG_STRING, - HBDeviceAssignFunc, NULL, HBDeviceShowFunc,WdIFSlotEmptyCheckFunc + HBDeviceAssignFunc, NULL, HBDeviceShowFunc, WdIFSlotEmptyCheckFunc }, { {"other_pgpool_hostname", CFGCXT_RELOAD, WATCHDOG_LIFECHECK, "Hostname of other pgpool node for watchdog connection.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, MAX_WATCHDOG_NUM + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_WATCHDOG_NUM }, NULL, "localhost", EMPTY_CONFIG_STRING, - OtherPPHostAssignFunc, NULL, OtherPPHostShowFunc,WdSlotEmptyCheckFunc + OtherPPHostAssignFunc, NULL, OtherPPHostShowFunc, WdSlotEmptyCheckFunc }, { {"health_check_user", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "User name for PostgreSQL backend health check.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, "nobody", { {"health_check_user", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default PostgreSQL user name to perform health check on node for which health_check_user[node-id] is not specified.", - CONFIG_VAR_TYPE_STRING,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_STRING, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_user, "nobody", @@ -1430,14 +1430,14 @@ static struct config_string_array ConfigureNamesStringArray[] = { {"health_check_password", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Password for PostgreSQL backend health check database user.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, VAR_HIDDEN_VALUE, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, VAR_HIDDEN_VALUE, MAX_NUM_BACKENDS }, NULL, "", { {"health_check_password", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default PostgreSQL user password to perform health check on node for which health_check_password[node-id] is not specified.", - CONFIG_VAR_TYPE_STRING,false, VAR_HIDDEN_VALUE|DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_VALUE | DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_password, "", @@ -1449,14 +1449,14 @@ static struct config_string_array ConfigureNamesStringArray[] = { {"health_check_database", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "The database name to be used to perform PostgreSQL backend health check.", - CONFIG_VAR_TYPE_STRING_ARRAY,true, 0, MAX_NUM_BACKENDS + CONFIG_VAR_TYPE_STRING_ARRAY, true, 0, MAX_NUM_BACKENDS }, NULL, "postgres", { {"health_check_database", CFGCXT_RELOAD, HEALTH_CHECK_CONFIG, "Default PostgreSQL database name to perform health check on node for which health_check_database[node-id] is not specified.", - CONFIG_VAR_TYPE_STRING,false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR + CONFIG_VAR_TYPE_STRING, false, DEFAULT_FOR_NO_VALUE_ARRAY_VAR }, &g_pool_config.health_check_database, "postgres", @@ -1478,297 +1478,297 @@ 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.port, 9999, - 1024,65535, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.pcp_port, 9898, - 1024,65535, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.num_init_children, 32, - 1,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.listen_backlog_multiplier, 32, - 1,INT_MAX, + 1, INT_MAX, NULL, NULL, NULL }, { {"child_life_time", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "pgpool-II child process life time in seconds.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.child_life_time, 300, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.client_idle_limit, 0, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, { {"connection_life_time", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "Cached connections expiration time in seconds.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.connection_life_time, 0, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, { {"child_max_connections", CFGCXT_INIT, CONNECTION_POOL_CONFIG, "A pgpool-II child process will be terminated after this many connections from clients.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.child_max_connections, 0, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, { {"authentication_timeout", CFGCXT_INIT, CONNECTION_CONFIG, "Time out value in seconds for client authentication.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.authentication_timeout, 0, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.max_pool, 4, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.sr_check_period, 0, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.recovery_timeout, 90, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - + { {"client_idle_limit_in_recovery", CFGCXT_SESSION, RECOVERY_CONFIG, "Time limit is seconds for the child connection, before it is terminated during the 2nd stage recovery.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.client_idle_limit_in_recovery, 0, - -1,INT_MAX, + -1, INT_MAX, NULL, NULL, NULL }, - + { {"search_primary_node_timeout", CFGCXT_RELOAD, FAILOVER_CONFIG, "Max time in seconds to search for primary node after failover.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.search_primary_node_timeout, 300, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_port, 9000, - 1024,INT_MAX, + 1024, INT_MAX, NULL, NULL, NULL }, - + { {"wd_priority", CFGCXT_INIT, WATCHDOG_CONFIG, "Watchdog node priority for leader election.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_priority, 1, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, { {"wd_interval", CFGCXT_INIT, WATCHDOG_CONFIG, "Time interval in seconds between life check.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_interval, 10, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_life_point, 3, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - + { {"wd_heartbeat_port", CFGCXT_INIT, WATCHDOG_CONFIG, "Port number for receiving heartbeat signal.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_heartbeat_port, 9694, - 1024,65535, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_heartbeat_keepalive, 2, - 1,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.wd_heartbeat_deadtime, 30, - 1,INT_MAX, + 1, INT_MAX, NULL, NULL, NULL }, { {"relcache_size", CFGCXT_INIT, CACHE_CONFIG, "Number of relation cache entry.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.relcache_size, 256, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - + { {"memqcache_memcached_port", CFGCXT_INIT, CACHE_CONFIG, "Port number of Memcached server.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.memqcache_memcached_port, 11211, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, { {"memqcache_max_num_cache", CFGCXT_INIT, CACHE_CONFIG, "Total number of cache entries.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.memqcache_max_num_cache, 1000000, - 0,INT_MAX, + 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, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.memqcache_expire, 0, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - + { {"memqcache_maxcache", CFGCXT_INIT, CACHE_CONFIG, "Maximum SELECT result size in bytes.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.memqcache_maxcache, 409600, - 0,INT_MAX, + 0, INT_MAX, NULL, NULL, NULL }, - + { {"memqcache_cache_block_size", CFGCXT_INIT, CACHE_CONFIG, "Cache block size in bytes.", - CONFIG_VAR_TYPE_INT,false, 0 + CONFIG_VAR_TYPE_INT, false, 0 }, &g_pool_config.memqcache_cache_block_size, 1048576, - 512,INT_MAX, + 512, INT_MAX, NULL, NULL, NULL }, @@ -1781,7 +1781,7 @@ static struct config_enum ConfigureNamesEnum[] = { {"syslog_facility", CFGCXT_RELOAD, LOGING_CONFIG, "syslog local faclity.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, &g_pool_config.syslog_facility, LOG_LOCAL0, @@ -1794,7 +1794,7 @@ static struct config_enum ConfigureNamesEnum[] = { {"log_error_verbosity", CFGCXT_SESSION, LOGING_CONFIG, "How much details about error should be emitted.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, &g_pool_config.log_error_verbosity, PGERROR_DEFAULT, @@ -1805,7 +1805,7 @@ static struct config_enum ConfigureNamesEnum[] = { {"client_min_messages", CFGCXT_SESSION, LOGING_CONFIG, "Which messages should be sent to client.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, &g_pool_config.client_min_messages, NOTICE, @@ -1816,20 +1816,20 @@ static struct config_enum ConfigureNamesEnum[] = { {"log_min_messages", CFGCXT_SESSION, LOGING_CONFIG, "Which messages should be emitted to server log.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, &g_pool_config.log_min_messages, WARNING, server_message_level_options, NULL, NULL, NULL, NULL }, - + { {"master_slave_sub_mode", CFGCXT_INIT, MASTER_SLAVE_CONFIG, "master/slave sub mode.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int*)&g_pool_config.master_slave_sub_mode, + (int *) &g_pool_config.master_slave_sub_mode, STREAM_MODE, master_slave_sub_mode_options, NULL, NULL, NULL, NULL @@ -1838,9 +1838,9 @@ static struct config_enum ConfigureNamesEnum[] = { {"log_standby_delay", CFGCXT_RELOAD, MASTER_SLAVE_CONFIG, "When to log standby delay.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int*)&g_pool_config.log_standby_delay, + (int *) &g_pool_config.log_standby_delay, LSD_NONE, log_standby_delay_options, NULL, NULL, NULL, NULL @@ -1849,20 +1849,20 @@ static struct config_enum ConfigureNamesEnum[] = { {"wd_lifecheck_method", CFGCXT_INIT, WATCHDOG_CONFIG, "method for watchdog lifecheck.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int*)&g_pool_config.wd_lifecheck_method, + (int *) &g_pool_config.wd_lifecheck_method, LIFECHECK_BY_HB, wd_lifecheck_method_options, NULL, 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, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int*)&g_pool_config.memqcache_method, + (int *) &g_pool_config.memqcache_method, SHMEM_CACHE, memqcache_method_options, NULL, NULL, NULL, NULL @@ -1871,9 +1871,9 @@ static struct config_enum ConfigureNamesEnum[] = { {"disable_load_balance_on_write", CFGCXT_RELOAD, LOAD_BALANCE_CONFIG, "Load balance behavior when write query is received.", - CONFIG_VAR_TYPE_ENUM,false, 0 + CONFIG_VAR_TYPE_ENUM, false, 0 }, - (int*)&g_pool_config.disable_load_balance_on_write, + (int *) &g_pool_config.disable_load_balance_on_write, DLBOW_TRANSACTION, disable_load_balance_on_write_options, NULL, NULL, NULL, NULL @@ -1889,33 +1889,33 @@ static struct config_grouped_array_var ConfigureVarGroups[] = { {"backend", CFGCXT_BOOT, CONNECTION_CONFIG, "backend configuration group.", - CONFIG_VAR_TYPE_GROUP,false, 0 + CONFIG_VAR_TYPE_GROUP, false, 0 }, - -1, /*until initialized*/ + -1, /* until initialized */ NULL }, { {"other_pgpool", CFGCXT_BOOT, WATCHDOG_CONFIG, "watchdog nodes configuration group.", - CONFIG_VAR_TYPE_GROUP,false, 0 + CONFIG_VAR_TYPE_GROUP, false, 0 }, - -1, /*until initialized*/ + -1, /* until initialized */ NULL }, { {"heartbeat", CFGCXT_BOOT, WATCHDOG_LIFECHECK, "heartbeat configuration group.", - CONFIG_VAR_TYPE_GROUP,false, 0 + CONFIG_VAR_TYPE_GROUP, false, 0 }, - -1, /*until initialized*/ + -1, /* until initialized */ NULL }, { {"health_check", CFGCXT_BOOT, HEALTH_CHECK_CONFIG, "backend health check configuration group.", - CONFIG_VAR_TYPE_GROUP,false, 0 + CONFIG_VAR_TYPE_GROUP, false, 0 }, - -1, /*until initialized*/ + -1, /* until initialized */ NULL }, /* End-of-list marker */ @@ -1939,22 +1939,22 @@ build_config_variables(void) { struct config_generic **all_vars; int i; - int num_vars = 0; + 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: */ initialize_config_gen(&conf->gen); conf->gen.vartype = CONFIG_VAR_TYPE_BOOL; num_vars++; } - + for (i = 0; ConfigureNamesInt[i].gen.name; i++) { struct config_int *conf = &ConfigureNamesInt[i]; - + initialize_config_gen(&conf->gen); conf->gen.vartype = CONFIG_VAR_TYPE_INT; num_vars++; @@ -1980,7 +1980,7 @@ build_config_variables(void) } num_vars++; } - + for (i = 0; ConfigureNamesLong[i].gen.name; i++) { struct config_long *conf = &ConfigureNamesLong[i]; @@ -1989,7 +1989,7 @@ build_config_variables(void) conf->gen.vartype = CONFIG_VAR_TYPE_LONG; num_vars++; } - + for (i = 0; ConfigureNamesDouble[i].gen.name; i++) { struct config_double *conf = &ConfigureNamesDouble[i]; @@ -2008,7 +2008,7 @@ build_config_variables(void) conf->reset_val = NULL; num_vars++; } - + for (i = 0; ConfigureNamesEnum[i].gen.name; i++) { struct config_enum *conf = &ConfigureNamesEnum[i]; @@ -2031,12 +2031,13 @@ build_config_variables(void) for (i = 0; ConfigureNamesStringArray[i].gen.name; i++) { struct config_string_array *conf = &ConfigureNamesStringArray[i]; + conf->gen.dynamic_array_var = true; initialize_config_gen(&conf->gen); conf->gen.vartype = CONFIG_VAR_TYPE_STRING_ARRAY; /* Assign the memory for reset vals */ - conf->reset_vals = palloc0(sizeof(char*) * conf->gen.max_elements); + conf->reset_vals = palloc0(sizeof(char *) * conf->gen.max_elements); if (conf->config_no_index.gen.name) { @@ -2052,6 +2053,7 @@ build_config_variables(void) for (i = 0; ConfigureNamesDoubleArray[i].gen.name; i++) { struct config_double_array *conf = &ConfigureNamesDoubleArray[i]; + conf->gen.dynamic_array_var = true; initialize_config_gen(&conf->gen); @@ -2074,10 +2076,10 @@ build_config_variables(void) num_vars++; all_vars = (struct config_generic **) - palloc(num_vars * sizeof(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; @@ -2098,10 +2100,10 @@ build_config_variables(void) 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; @@ -2116,12 +2118,13 @@ build_config_variables(void) build_variable_groups(); } -static void build_variable_groups(void) +static void +build_variable_groups(void) { /* we build these by hand */ /* group 1. Backend config vars */ ConfigureVarGroups[0].var_count = 5; - ConfigureVarGroups[0].var_list = palloc0(sizeof(struct config_generic*) * ConfigureVarGroups[0].var_count); + ConfigureVarGroups[0].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[0].var_count); ConfigureVarGroups[0].var_list[0] = find_option("backend_hostname", FATAL); ConfigureVarGroups[0].var_list[0]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[0].var_list[1] = find_option("backend_port", FATAL); @@ -2136,7 +2139,7 @@ static void build_variable_groups(void) /* group 2. other_pgpool config vars */ ConfigureVarGroups[1].var_count = 3; - ConfigureVarGroups[1].var_list = palloc0(sizeof(struct config_generic*) * ConfigureVarGroups[1].var_count); + ConfigureVarGroups[1].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[1].var_count); /* backend hostname */ ConfigureVarGroups[1].var_list[0] = find_option("other_pgpool_hostname", FATAL); ConfigureVarGroups[1].var_list[0]->flags |= VAR_PART_OF_GROUP; @@ -2149,7 +2152,7 @@ static void build_variable_groups(void) /* group 3. heartbeat config vars */ ConfigureVarGroups[2].var_count = 3; - ConfigureVarGroups[2].var_list = palloc0(sizeof(struct config_generic*) * ConfigureVarGroups[2].var_count); + ConfigureVarGroups[2].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[2].var_count); /* backend hostname */ ConfigureVarGroups[2].var_list[0] = find_option("heartbeat_device", FATAL); ConfigureVarGroups[2].var_list[0]->flags |= VAR_PART_OF_GROUP; @@ -2161,7 +2164,7 @@ static void build_variable_groups(void) /* group 4. health_check config vars */ ConfigureVarGroups[3].var_count = 8; - ConfigureVarGroups[3].var_list = palloc0(sizeof(struct config_generic*) * ConfigureVarGroups[3].var_count); + ConfigureVarGroups[3].var_list = palloc0(sizeof(struct config_generic *) * ConfigureVarGroups[3].var_count); ConfigureVarGroups[3].var_list[0] = find_option("health_check_period", FATAL); ConfigureVarGroups[3].var_list[0]->flags |= VAR_PART_OF_GROUP; ConfigureVarGroups[3].var_list[1] = find_option("health_check_timeout", FATAL); @@ -2187,17 +2190,21 @@ static void build_variable_groups(void) * 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) +static void +sort_config_vars(void) { - int i,j; + int i, + j; + for (i = 0; i < num_all_parameters; ++i) { - struct config_generic* gconfi = all_parameters[i]; - int leni = strlen(gconfi->name); + 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); + struct config_generic *gconfj = all_parameters[j]; + int lenj = strlen(gconfj->name); if (leni < lenj) { @@ -2214,9 +2221,10 @@ static void sort_config_vars(void) * Initialize all variables to its compiled-in default. */ static void -initialize_variables_with_default(struct config_generic * gconf) +initialize_variables_with_default(struct config_generic *gconf) { - int i; + int i; + for (i = 0; i < gconf->max_elements; i++) { gconf->sources[i] = PGC_S_DEFAULT; @@ -2228,7 +2236,8 @@ initialize_variables_with_default(struct config_generic * gconf) /* Also set the default value for index free record if any */ if (gconf->dynamic_array_var && gconf->flags & ARRAY_VAR_ALLOW_NO_INDEX) { - struct config_generic* idx_free_record = get_index_free_record_if_any(gconf); + struct config_generic *idx_free_record = get_index_free_record_if_any(gconf); + if (idx_free_record) { ereport(DEBUG1, @@ -2244,223 +2253,224 @@ initialize_variables_with_default(struct config_generic * gconf) break; 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)(CFGCXT_BOOT, newval, ERROR); - } - else { - *conf->variable = conf->reset_val = newval; - } - break; - } + struct config_bool *conf = (struct config_bool *) gconf; + bool newval = conf->boot_val; - 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)(CFGCXT_BOOT, newval, ERROR); - } - else - { - *conf->variable = newval; + if (conf->assign_func) + { + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); + } + else + { + *conf->variable = conf->reset_val = newval; + } + break; } - 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)(CFGCXT_BOOT, newval, ERROR); - } - else + case CONFIG_VAR_TYPE_INT: { - *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; + struct config_int *conf = (struct config_int *) gconf; + int newval = conf->boot_val; - for (i = 0; i < gconf->max_elements; i ++) - { if (conf->assign_func) { - (*conf->assign_func)(CFGCXT_BOOT, newval, i, ERROR); + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); } else { - *conf->variable[i] = newval; + *conf->variable = newval; } - conf->reset_vals[i] = newval; - } - break; - } + conf->reset_val = newval; - case CONFIG_VAR_TYPE_DOUBLE_ARRAY: - { - struct config_double_array *conf = (struct config_double_array *) gconf; - double newval = conf->boot_val; - int i; + break; + } - for (i = 0; i < gconf->max_elements; i ++) + 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)(CFGCXT_BOOT, newval, i, ERROR); + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); } else { - *conf->variable[i] = newval; + *conf->variable = newval; } - conf->reset_vals[i] = newval; - } - break; - } + conf->reset_val = newval; - 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)(CFGCXT_BOOT, newval, ERROR); - } - else - { - *conf->variable = conf->reset_val = newval; + break; } - break; - } - case CONFIG_VAR_TYPE_STRING: - { - struct config_string *conf = (struct config_string *) gconf; - char *newval = (char*)conf->boot_val; - - if (conf->assign_func) + case CONFIG_VAR_TYPE_INT_ARRAY: { - (*conf->assign_func)(CFGCXT_BOOT, newval, ERROR); + struct config_int_array *conf = (struct config_int_array *) gconf; + int newval = conf->boot_val; + int i; + + for (i = 0; i < gconf->max_elements; i++) + { + if (conf->assign_func) + { + (*conf->assign_func) (CFGCXT_BOOT, newval, i, ERROR); + } + else + { + *conf->variable[i] = newval; + } + conf->reset_vals[i] = newval; + } + break; } - else + + case CONFIG_VAR_TYPE_DOUBLE_ARRAY: { - *conf->variable = newval?pstrdup(newval):NULL; - } + struct config_double_array *conf = (struct config_double_array *) gconf; + double newval = conf->boot_val; + int i; - conf->reset_val = newval?pstrdup(newval):NULL; + for (i = 0; i < gconf->max_elements; i++) + { + if (conf->assign_func) + { + (*conf->assign_func) (CFGCXT_BOOT, newval, i, ERROR); + } + else + { + *conf->variable[i] = newval; + } + conf->reset_vals[i] = newval; + } + break; + } - if (conf->process_func) + case CONFIG_VAR_TYPE_LONG: { - (*conf->process_func)(newval, ERROR); - } - break; - } + struct config_long *conf = (struct config_long *) gconf; + long newval = conf->boot_val; - case CONFIG_VAR_TYPE_STRING_ARRAY: - { - struct config_string_array *conf = (struct config_string_array *) gconf; - char *newval = (char*)conf->boot_val; - int i; + if (conf->assign_func) + { + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); + } + else + { + *conf->variable = conf->reset_val = newval; + } + break; + } - for (i = 0; i < gconf->max_elements; i ++) + case CONFIG_VAR_TYPE_STRING: { + struct config_string *conf = (struct config_string *) gconf; + char *newval = (char *) conf->boot_val; if (conf->assign_func) { - (*conf->assign_func)(CFGCXT_BOOT, newval, i, ERROR); + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); } else { - *conf->variable[i] = newval?pstrdup(newval):NULL; + *conf->variable = newval ? pstrdup(newval) : NULL; } - if (newval) - conf->reset_vals[i] = pstrdup(newval); - } - break; - } - - case CONFIG_VAR_TYPE_ENUM: - { - struct config_enum *conf = (struct config_enum *) gconf; - int newval = conf->boot_val; + conf->reset_val = newval ? pstrdup(newval) : NULL; - if (conf->assign_func) - { - (*conf->assign_func)(CFGCXT_BOOT, newval, ERROR); - } - else - { - *conf->variable = newval; + if (conf->process_func) + { + (*conf->process_func) (newval, ERROR); + } + break; } - conf->reset_val = newval; - if (conf->process_func) + case CONFIG_VAR_TYPE_STRING_ARRAY: { - (*conf->process_func)(newval, ERROR); - } + struct config_string_array *conf = (struct config_string_array *) gconf; + char *newval = (char *) conf->boot_val; + int i; - break; - } + for (i = 0; i < gconf->max_elements; i++) + { - case CONFIG_VAR_TYPE_STRING_LIST: - { - struct config_string_list *conf = (struct config_string_list *) gconf; - char *newval = (char*)conf->boot_val; + if (conf->assign_func) + { + (*conf->assign_func) (CFGCXT_BOOT, newval, i, ERROR); + } + else + { + *conf->variable[i] = newval ? pstrdup(newval) : NULL; + } - if (conf->assign_func) - { - (*conf->assign_func)(CFGCXT_BOOT, newval, ERROR); + if (newval) + conf->reset_vals[i] = pstrdup(newval); + } + break; } - else + + case CONFIG_VAR_TYPE_ENUM: { - if (strcmp(gconf->name, "black_query_pattern_list") == 0) + struct config_enum *conf = (struct config_enum *) gconf; + int newval = conf->boot_val; + + if (conf->assign_func) { - *conf->variable = get_list_from_string_regex_delim(newval, conf->seperator, conf->list_elements_count); + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); } else { - *conf->variable = get_list_from_string(newval,conf->seperator, conf->list_elements_count); + *conf->variable = newval; + } + conf->reset_val = newval; + + if (conf->process_func) + { + (*conf->process_func) (newval, ERROR); } - if (conf->compute_regex) + break; + } + + case CONFIG_VAR_TYPE_STRING_LIST: + { + struct config_string_list *conf = (struct config_string_list *) gconf; + char *newval = (char *) conf->boot_val; + + if (conf->assign_func) + { + (*conf->assign_func) (CFGCXT_BOOT, newval, ERROR); + } + else { - int i; - for (i=0;i < *conf->list_elements_count; i++) + if (strcmp(gconf->name, "black_query_pattern_list") == 0) + { + *conf->variable = get_list_from_string_regex_delim(newval, conf->seperator, conf->list_elements_count); + } + else + { + *conf->variable = get_list_from_string(newval, conf->seperator, conf->list_elements_count); + } + + if (conf->compute_regex) { - add_regex_pattern((const char*)conf->gen.name, (*conf->variable)[i]); + int i; + + for (i = 0; i < *conf->list_elements_count; i++) + { + add_regex_pattern((const char *) conf->gen.name, (*conf->variable)[i]); + } } } - } - /* save the string value */ - conf->reset_val = newval?pstrdup(newval):NULL; + /* save the string value */ + conf->reset_val = newval ? pstrdup(newval) : NULL; - if (conf->current_val) - pfree(conf->current_val); + if (conf->current_val) + pfree(conf->current_val); - conf->current_val = newval?pstrdup(newval):NULL; - break; - } + conf->current_val = newval ? pstrdup(newval) : NULL; + break; + } } } @@ -2470,12 +2480,13 @@ initialize_variables_with_default(struct config_generic * gconf) * array of pointers in pallocd strings. number of elements are set to * n. */ -static char **get_list_from_string(const char *str, const char *delimi, int *n) +static char ** +get_list_from_string(const char *str, const char *delimi, int *n) { - char *token; - char **tokens; - char *temp_string; - const int MAXTOKENS = 256; + char *token; + char **tokens; + char *temp_string; + const int MAXTOKENS = 256; *n = 0; @@ -2486,25 +2497,25 @@ static char **get_list_from_string(const char *str, const char *delimi, int *n) tokens = palloc(MAXTOKENS * sizeof(char *)); ereport(DEBUG3, - (errmsg("extracting string tokens from [%s] based on %s", temp_string,delimi))); - - for (token = strtok(temp_string, delimi); token != NULL ; token = strtok(NULL, delimi)) + (errmsg("extracting string tokens from [%s] based on %s", temp_string, delimi))); + + for (token = strtok(temp_string, delimi); token != NULL; token = strtok(NULL, delimi)) { tokens[*n] = pstrdup(token); ereport(DEBUG3, - (errmsg("initializing pool configuration"), + (errmsg("initializing pool configuration"), errdetail("extracting string tokens [token[%d]: %s]", *n, tokens[*n]))); - + (*n)++; - - if ( ((*n) % MAXTOKENS ) == 0) + + if (((*n) % MAXTOKENS) == 0) { - tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n)/MAXTOKENS) +1) )); + tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n) / MAXTOKENS) + 1))); } } /* how about reclaiming the unused space */ if (*n > 0) - tokens = repalloc(tokens, (sizeof(char *) * (*n) )); + tokens = repalloc(tokens, (sizeof(char *) * (*n))); pfree(temp_string); return tokens; @@ -2516,15 +2527,18 @@ static char **get_list_from_string(const char *str, const char *delimi, int *n) * pointers in pallocd strings. number of elements are set * to n. */ -static char **get_list_from_string_regex_delim(const char *input, const char *delimi, int *n) +static char ** +get_list_from_string_regex_delim(const char *input, const char *delimi, int *n) { #ifndef POOL_PRIVATE - int j = 0; - char *output; - char *str; - char *buf, * str_temp; - char **tokens; - const int MAXTOKENS = 256; + int j = 0; + char *output; + char *str; + char *buf, + *str_temp; + char **tokens; + const int MAXTOKENS = 256; + *n = 0; if (input == NULL || *input == '\0') @@ -2533,8 +2547,9 @@ static char **get_list_from_string_regex_delim(const char *input, const char *de tokens = palloc(MAXTOKENS * sizeof(char *)); if (*(input + strlen(input) - 1) != *delimi || *(input + strlen(input) - 2) == '\\') { - int len = strlen(input) + 2; - str = palloc(len); + int len = strlen(input) + 2; + + str = palloc(len); snprintf(str, len, "%s;", input); } else @@ -2545,7 +2560,7 @@ static char **get_list_from_string_regex_delim(const char *input, const char *de buf = str; str_temp = str; - while(*str_temp != '\0') + while (*str_temp != '\0') { if (*str_temp == '\\') { @@ -2557,19 +2572,19 @@ static char **get_list_from_string_regex_delim(const char *input, const char *de output = (char *) palloc(j + 1); StrNCpy(output, buf, j + 1); - /* replace escape character of "'"*/ + /* replace escape character of "'" */ tokens[*n] = string_replace(output, "\\'", "'"); ereport(DEBUG3, - (errmsg("initializing pool configuration"), - errdetail("extracting string tokens [token[%d]: %s]", *n, tokens[*n]))); + (errmsg("initializing pool configuration"), + errdetail("extracting string tokens [token[%d]: %s]", *n, tokens[*n]))); (*n)++; buf = str_temp + 1; j = 0; - if ( ((*n) % MAXTOKENS ) == 0) - tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n)/MAXTOKENS) + 1) )); + if (((*n) % MAXTOKENS) == 0) + tokens = repalloc(tokens, (MAXTOKENS * sizeof(char *) * (((*n) / MAXTOKENS) + 1))); } else { @@ -2579,7 +2594,7 @@ static char **get_list_from_string_regex_delim(const char *input, const char *de } if (*n > 0) - tokens = repalloc(tokens, (sizeof(char *) * (*n) )); + tokens = repalloc(tokens, (sizeof(char *) * (*n))); pfree(str); @@ -2598,10 +2613,9 @@ InitializeConfigOptions(void) int i; /* - * Before we do anything set the log_min_messages to ERROR. - * Reason for doing that is before the log_min_messages gets initialized - * with the actual value the pgpool-II log should not get flooded by DEBUG - * messages + * Before we do anything set the log_min_messages to ERROR. Reason for + * doing that is before the log_min_messages gets initialized with the + * actual value the pgpool-II log should not get flooded by DEBUG messages */ g_pool_config.log_min_messages = ERROR; g_pool_config.syslog_facility = LOG_LOCAL0; @@ -2626,23 +2640,25 @@ InitializeConfigOptions(void) * if the index is not present at end of the name the function * will return true and out parameter index will be assigned with -ve value */ -static bool get_index_in_var_name(struct config_generic* record, const char* name, int *index, int elevel) +static bool +get_index_in_var_name(struct config_generic *record, const char *name, int *index, int elevel) { - char *ptr; - int index_start_index = strlen(record->name); + char *ptr; + int index_start_index = strlen(record->name); + if (strlen(name) <= index_start_index) { /* no index is provided */ *index = -1; return true; } - ptr = (char*)(name + index_start_index); + ptr = (char *) (name + index_start_index); while (*ptr) { if (isdigit(*ptr) == 0) { ereport(elevel, - (errmsg("invalid index value for parameter \"%s\" ",name), + (errmsg("invalid index value for parameter \"%s\" ", name), (errdetail("index part contains the invalid non digit character")))); return false; } @@ -2659,16 +2675,20 @@ static bool get_index_in_var_name(struct config_generic* record, const char* nam static struct config_generic * find_option(const char *name, int elevel) { - int i; + int i; + for (i = 0; i < num_all_parameters; i++) { - struct config_generic* gconf = all_parameters[i]; + struct config_generic *gconf = all_parameters[i]; + if (gconf->dynamic_array_var) { - int index_start_index = strlen(gconf->name); + 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's name part + * For dynamic array type vars the key also have the index at the + * end e.g. backend_hostname0 so we only comapare the key's name + * part */ if (!strncmp(gconf->name, name, index_start_index)) return gconf; @@ -2690,11 +2710,11 @@ find_option(const char *name, int elevel) * 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, +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) @@ -2703,7 +2723,7 @@ config_enum_lookup_by_name(struct config_enum * record, const char *value, return TRUE; } } - + *retval = 0; return FALSE; } @@ -2711,23 +2731,26 @@ config_enum_lookup_by_name(struct config_enum * record, const char *value, bool set_config_options(ConfigVariable *head_p, - ConfigContext context, GucSource source, int elevel) + 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); + return config_post_processor(context, elevel); } -bool set_one_config_option(const char *name, const char *value, - ConfigContext context, GucSource source, int 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 config_post_processor(context, elevel); return false; } @@ -2736,21 +2759,22 @@ setConfigOption(const char *name, const char *value, ConfigContext context, GucSource source, int elevel) { struct config_generic *record; - int index_val = -1; + int index_val = -1; ereport(DEBUG2, - (errmsg("set_config_option \"%s\" = \"%s\"", name,value))); - + (errmsg("set_config_option \"%s\" = \"%s\"", name, value))); + record = find_option(name, elevel); - + if (record == NULL) { - /* we emit only INFO message when setting the option from - * configuration file. - * As the conf file may still contain some configuration parameters only exist - * in older version and does not exist anymore + /* + * we emit only INFO message when setting the option from + * configuration file. As the conf file may still contain some + * configuration parameters only exist in older version and does not + * exist anymore */ - ereport(source == PGC_S_FILE?INFO:elevel, + ereport(source == PGC_S_FILE ? INFO : elevel, (errmsg("unrecognized configuration parameter \"%s\"", name))); return false; } @@ -2758,8 +2782,8 @@ setConfigOption(const char *name, const char *value, { if (get_index_in_var_name(record, name, &index_val, elevel) == false) return false; - - if (index_val < 0 ) + + if (index_val < 0) { /* index is not provided */ if (record->flags & ARRAY_VAR_ALLOW_NO_INDEX) @@ -2782,10 +2806,10 @@ setConfigOption(const char *name, const char *value, } static bool -setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const char* name, +setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const char *name, const char *value, ConfigContext context, int elevel) { - int index; + int index; if (record->dynamic_array_var == false) { @@ -2804,10 +2828,12 @@ setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const ch for (index = 0; index < record->max_elements; index++) { - /* only elements having the values from the default source - * can be updated*/ + /* + * only elements having the values from the default source can be + * updated + */ if (record->sources[index] != PGC_S_DEFAULT - && record->sources[index] != PGC_S_VALUE_DEFAULT ) + && record->sources[index] != PGC_S_VALUE_DEFAULT) continue; setConfigOptionVar(record, record->name, index, value, CFGCXT_INIT, PGC_S_VALUE_DEFAULT, elevel); @@ -2816,10 +2842,10 @@ setConfigOptionArrayVarWithConfigDefault(struct config_generic *record, const ch } static bool -setConfigOptionVar(struct config_generic *record, const char* name, int index_val, const char *value, - ConfigContext context, GucSource source, int elevel) +setConfigOptionVar(struct config_generic *record, const char *name, int index_val, const char *value, + ConfigContext context, GucSource source, int elevel) { - bool reset = false; + bool reset = false; switch (record->context) { @@ -2828,10 +2854,13 @@ setConfigOptionVar(struct config_generic *record, const char* name, int index_va { if (context == CFGCXT_RELOAD) { - /* Do not treat it as an error. Since the RELOAD context is used by reload config mechanism of - * pgpool-II and the configuration file always contain all the values, including - * those that are not allowed to be changed in reload context. - * So silently ignoring this for the time being is the best way to go until we enhance the logic + /* + * Do not treat it as an error. Since the RELOAD context + * is used by reload config mechanism of pgpool-II and the + * configuration file always contain all the values, + * including those that are not allowed to be changed in + * reload context. So silently ignoring this for the time + * being is the best way to go until we enhance the logic * around this */ ereport(DEBUG2, @@ -2886,12 +2915,12 @@ setConfigOptionVar(struct config_generic *record, const char* name, int index_va break; default: - { - ereport(elevel, - (errmsg("invalid record context, value for parameter \"%s\" cannot be changed", - name))); - return false; - } + { + ereport(elevel, + (errmsg("invalid record context, value for parameter \"%s\" cannot be changed", + name))); + return false; + } break; } @@ -2905,19 +2934,22 @@ setConfigOptionVar(struct config_generic *record, const char* name, int index_va if (record->flags & ARRAY_VAR_ALLOW_NO_INDEX) { - struct config_generic* idx_free_record = get_index_free_record_if_any(record); + struct config_generic *idx_free_record = get_index_free_record_if_any(record); + if (idx_free_record) { - bool ret; + bool ret; + ereport(DEBUG1, (errmsg("parameter \"%s\" is an array type variable and allows index-free value as well", name))); ret = setConfigOptionVar(idx_free_record, name, index_val, value, - context, source, elevel); + context, source, elevel); if (idx_free_record->flags & DEFAULT_FOR_NO_VALUE_ARRAY_VAR) { const char *newVal; - /* we need to update the default values*/ + + /* we need to update the default values */ ereport(DEBUG2, (errmsg("modifying the array index values for parameter \"%s\" source = %d", name, source))); @@ -2931,7 +2963,7 @@ setConfigOptionVar(struct config_generic *record, const char* name, int index_va newVal = value; setConfigOptionArrayVarWithConfigDefault(record, name, newVal, - context, elevel); + context, elevel); } return ret; } @@ -2950,520 +2982,522 @@ setConfigOptionVar(struct config_generic *record, const char* name, int index_va switch (record->vartype) { case CONFIG_VAR_TYPE_GROUP: - ereport(ERROR,(errmsg("invalid config variable type. operation not allowed"))); + ereport(ERROR, (errmsg("invalid config variable type. operation not allowed"))); break; 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); + struct config_bool *conf = (struct config_bool *) record; + bool newval = conf->boot_val; - } - else if (source == PGC_S_DEFAULT) - { - newval = conf->boot_val; - } - else - { - /* Reset */ - newval = conf->reset_val; - reset = true; - } - if (conf->assign_func) - { - if ((*conf->assign_func)(context, newval, elevel) == false) - return false; - } - else - *conf->variable = newval; + if (value != NULL) + { + newval = eval_logical(value); - if (context == CFGCXT_INIT) - conf->reset_val = newval; - } + } + else if (source == PGC_S_DEFAULT) + { + newval = conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_val; + reset = true; + } + 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; - reset = true; - } - - 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; - } + struct config_int *conf = (struct config_int *) record; + int newval; - if (conf->assign_func) - { - if ((*conf->assign_func)(context, newval, elevel) == false) + if (value != NULL) + { + newval = atoi(value); + } + else if (source == PGC_S_DEFAULT) + { + newval = conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_val; + reset = true; + } + + 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; - } - else - { - *conf->variable = newval; - } + } - if (context == CFGCXT_INIT) - conf->reset_val = newval; - } + 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; - reset = true; - } - - 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) + 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; + reset = true; + } + + 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; - } - else - { - *conf->variable = newval; - } + } - if (context == CFGCXT_INIT) - conf->reset_val = newval; + 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 > record->max_elements) { - ereport(elevel, - (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)", - index_val, name, - 0, record->max_elements))); - return false; - } + struct config_int_array *conf = (struct config_int_array *) record; + int newval; - if (value != NULL) - { - newval = atoi(value); - } - else if (source == PGC_S_DEFAULT) - { - newval = conf->boot_val; - } - else - { - /* Reset */ - newval = conf->reset_vals[index_val]; - reset = true; - } + if (index_val < 0 || index_val > record->max_elements) + { + ereport(elevel, + (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)", + index_val, name, + 0, record->max_elements))); + return false; + } - 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 (value != NULL) + { + newval = atoi(value); + } + else if (source == PGC_S_DEFAULT) + { + newval = conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_vals[index_val]; + reset = true; + } - if (conf->assign_func) - { - if ((*conf->assign_func)(context, newval, index_val, elevel) == false) + 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; - } - else - { - *conf->variable[index_val] = newval; - } + } + + 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; + 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 > record->max_elements) - { - ereport(elevel, - (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)", - index_val, name, - 0, record->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]; - reset = true; - } - - 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) + struct config_double_array *conf = (struct config_double_array *) record; + double newval; + + if (index_val < 0 || index_val > record->max_elements) + { + ereport(elevel, + (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)", + index_val, name, + 0, record->max_elements))); return false; - } - else - { - *conf->variable[index_val] = newval; - } + } - if (context == CFGCXT_INIT) - conf->reset_vals[index_val] = newval; + if (value != NULL) + { + newval = atof(value); + } + else if (source == PGC_S_DEFAULT) + { + newval = conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_vals[index_val]; + reset = true; + } - } + 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; - int64 newval; - - if (value != NULL) - { - newval = pool_atoi64(value); - } - else if (source == PGC_S_DEFAULT) - { - newval = conf->boot_val; - } - else - { - /* Reset */ - newval = conf->reset_val; - reset = true; - } - - 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) + struct config_long *conf = (struct config_long *) record; + int64 newval; + + if (value != NULL) + { + newval = pool_atoi64(value); + } + else if (source == PGC_S_DEFAULT) + { + newval = conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_val; + reset = true; + } + + 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; - } - else - { - *conf->variable = newval; - } + } - if (context == CFGCXT_INIT) - conf->reset_val = newval; + 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 = (char*)value; - } - else if (source == PGC_S_DEFAULT) - { - newval = (char*)conf->boot_val; - } - else - { - /* Reset */ - newval = conf->reset_val; - reset = true; - } + struct config_string *conf = (struct config_string *) record; + char *newval = NULL; - if (conf->assign_func) - { - if ((*conf->assign_func)(context, newval, elevel) == false) - return false; - } - else - { - if (*conf->variable) - pfree(*conf->variable); + if (value != NULL) + { + newval = (char *) value; + } + else if (source == PGC_S_DEFAULT) + { + newval = (char *) conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_val; + reset = true; + } - *conf->variable = newval?pstrdup(newval):NULL; - } - if (context == CFGCXT_INIT) - { - if (conf->reset_val) - pfree(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->reset_val = newval?pstrdup(newval):NULL; - } - if (conf->process_func) - { - (*conf->process_func)(newval, elevel); + *conf->variable = newval ? pstrdup(newval) : NULL; + } + if (context == CFGCXT_INIT) + { + if (conf->reset_val) + pfree(conf->reset_val); + + conf->reset_val = newval ? pstrdup(newval) : NULL; + } + 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 > record->max_elements) { - ereport(elevel, - (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)", - index_val, name, - 0, record->max_elements))); - return false; - } + struct config_string_array *conf = (struct config_string_array *) record; + char *newval = NULL; - if (value != NULL) - { - newval = (char*)value; - } - else if (source == PGC_S_DEFAULT) - { - newval = (char*)conf->boot_val; - } - else - { - /* Reset */ - newval = conf->reset_vals[index_val]; - reset = true; - } - - if (conf->assign_func) - { - if ((*conf->assign_func)(context, newval, index_val,elevel) == false) + if (index_val < 0 || index_val > record->max_elements) + { + ereport(elevel, + (errmsg("%d index outside the valid range for parameter \"%s\" (%d .. %d)", + index_val, name, + 0, record->max_elements))); return false; - } - else - { - if (*conf->variable[index_val]) - pfree(*conf->variable[index_val]); + } - *conf->variable[index_val] = newval?pstrdup(newval):NULL; - } - if (context == CFGCXT_INIT) - { - if (conf->reset_vals[index_val]) - pfree(conf->reset_vals[index_val]); + if (value != NULL) + { + newval = (char *) value; + } + else if (source == PGC_S_DEFAULT) + { + newval = (char *) conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_vals[index_val]; + reset = true; + } + + 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->reset_vals[index_val] = newval?pstrdup(newval):NULL; + *conf->variable[index_val] = newval ? pstrdup(newval) : NULL; + } + if (context == CFGCXT_INIT) + { + if (conf->reset_vals[index_val]) + pfree(conf->reset_vals[index_val]); + + conf->reset_vals[index_val] = newval ? pstrdup(newval) : NULL; + } } - } 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) - { - newval = (char*)conf->boot_val; - } - else - { - /* Reset */ - newval = conf->reset_val; - reset = true; - } + struct config_string_list *conf = (struct config_string_list *) record; + char *newval = NULL; - if (conf->assign_func) - { - if ((*conf->assign_func)(context, newval, elevel) == false) + if (value != NULL) { - return false; + newval = (char *) value; } - } - else - { - if (*conf->variable) + else if (source == PGC_S_DEFAULT) { - 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); + newval = (char *) conf->boot_val; + } + else + { + /* Reset */ + newval = conf->reset_val; + reset = true; } - if (strcmp(name, "black_query_pattern_list") == 0) + if (conf->assign_func) { - *conf->variable = get_list_from_string_regex_delim(newval, conf->seperator, conf->list_elements_count); + if ((*conf->assign_func) (context, newval, elevel) == false) + { + return false; + } } else { - *conf->variable = get_list_from_string(newval, conf->seperator, conf->list_elements_count); - } + if (*conf->variable) + { + int i; - if (conf->compute_regex) - { - /* TODO clear the old regex array please */ - int i; - for (i=0;i < *conf->list_elements_count; 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); + } + + if (strcmp(name, "black_query_pattern_list") == 0) + { + *conf->variable = get_list_from_string_regex_delim(newval, conf->seperator, conf->list_elements_count); + } + else { - add_regex_pattern(conf->gen.name, (*conf->variable)[i]); + *conf->variable = get_list_from_string(newval, conf->seperator, conf->list_elements_count); + } + + if (conf->compute_regex) + { + /* TODO clear the old regex 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 (context == CFGCXT_INIT) + { + if (conf->reset_val) + pfree(conf->reset_val); - conf->reset_val = newval?pstrdup(newval):NULL; - } + conf->reset_val = newval ? pstrdup(newval) : NULL; + } - /* save the string value */ - if (conf->current_val) - pfree(conf->current_val); + /* save the string value */ + if (conf->current_val) + pfree(conf->current_val); - conf->current_val = newval?pstrdup(newval):NULL; - } + conf->current_val = newval ? pstrdup(newval) : 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; - reset = true; - } - - if (value && !config_enum_lookup_by_name(conf, value, &newval)) { + 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; + reset = true; + } + + if (value && !config_enum_lookup_by_name(conf, value, &newval)) + { + + char *hintmsg = NULL; - char *hintmsg = NULL; - #ifndef POOL_PRIVATE - hintmsg = config_enum_get_options(conf, - "Available values: ", - ".", ", "); + 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) + ereport(elevel, + (errmsg("invalid value for parameter \"%s\": \"%s\"", + name, value), + hintmsg ? errhint("%s", hintmsg) : 0)); + + if (hintmsg) + pfree(hintmsg); return false; - } - else - { - *conf->variable = newval; - } + } - if (context == CFGCXT_INIT) - conf->reset_val = newval; + if (conf->assign_func) + { + if ((*conf->assign_func) (context, newval, elevel) == false) + return false; + } + else + { + *conf->variable = newval; + } - if (conf->process_func) - { - (*conf->process_func)(newval, elevel); - } + if (context == CFGCXT_INIT) + conf->reset_val = newval; - break; - } + if (conf->process_func) + { + (*conf->process_func) (newval, elevel); + } + + break; + } } if (record->dynamic_array_var) { @@ -3503,16 +3537,16 @@ setConfigOptionVar(struct config_generic *record, const char* name, int index_va * 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, +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++) { @@ -3522,7 +3556,7 @@ config_enum_get_options(struct config_enum * record, const char *prefix, 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 @@ -3536,33 +3570,36 @@ config_enum_get_options(struct config_enum * record, const char *prefix, 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) +static bool +BackendWeightAssignFunc(ConfigContext context, double newval, int index, int elevel) { - double old_v = g_pool_config.backend_desc->backend_info[index].unnormalized_weight; + 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 + * 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), + (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) +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; @@ -3580,57 +3617,63 @@ static bool BackendPortAssignFunc (ConfigContext context, int newval, int index, { if (context != CFGCXT_RELOAD) ereport(WARNING, - (errmsg("backend_port%d cannot be changed in context %d and backend status = %d",index,context,backend_status))); + (errmsg("backend_port%d cannot be changed in context %d and backend status = %d", index, context, backend_status))); return false; } return true; } -static bool BackendHostAssignFunc (ConfigContext context, char* newval, int index, int elevel) +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); + strlcpy(g_pool_config.backend_desc->backend_info[index].backend_hostname, newval, MAX_DB_HOST_NAMELEN - 1); return true; } /* silent the warning in reload contxt */ if (context != CFGCXT_RELOAD) ereport(WARNING, - (errmsg("backend_hostname%d cannot be changed in context %d and backend status = %d",index,context,backend_status))); + (errmsg("backend_hostname%d cannot be changed in context %d and backend status = %d", index, context, backend_status))); return false; } -static bool BackendDataDirAssignFunc (ConfigContext context, char* newval, int index, int elevel) +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); + strlcpy(g_pool_config.backend_desc->backend_info[index].backend_data_directory, newval, MAX_PATH_LENGTH - 1); return true; } /* silent the warning in reload contxt */ if (context != CFGCXT_RELOAD) ereport(WARNING, - (errmsg("backend_data_directory%d cannot be changed in context %d and backend status = %d",index,context,backend_status))); + (errmsg("backend_data_directory%d cannot be changed in context %d and backend status = %d", index, context, backend_status))); return false; } -static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int index, int elevel) +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; + 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) @@ -3639,14 +3682,15 @@ static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int ind pfree(flags); ereport(elevel, - (errmsg("invalid configuration for key \"backend_flag%d\"",index), + (errmsg("invalid configuration for key \"backend_flag%d\"", index), errdetail("unable to get backend flags"))); return false; } - for (i=0;i<n;i++) + for (i = 0; i < n; i++) { - int k; + int k; + if (!strcmp(flags[i], "ALLOW_TO_FAILOVER")) { if (disallow_to_failover_is_specified) @@ -3655,7 +3699,7 @@ static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int ind pfree(flags[k]); pfree(flags); ereport(elevel, - (errmsg("invalid configuration for key \"backend_flag%d\"",index), + (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; } @@ -3663,7 +3707,7 @@ static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int ind allow_to_failover_is_specified = true; } - + else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER")) { if (allow_to_failover_is_specified) @@ -3673,7 +3717,7 @@ static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int ind pfree(flags); ereport(elevel, - (errmsg("invalid configuration for key \"backend_flag%d\"",index), + (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; } @@ -3685,11 +3729,11 @@ static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int ind { flag |= POOL_ALWAYS_MASTER; } - + else { ereport(elevel, - (errmsg("invalid configuration for key \"backend_flag%d\"",index), + (errmsg("invalid configuration for key \"backend_flag%d\"", index), errdetail("unknown backend flag:%s", flags[i]))); for (k = i; k < n; k++) pfree(flags[k]); @@ -3701,17 +3745,20 @@ static bool BackendFlagsAssignFunc (ConfigContext context, char* newval, int ind g_pool_config.backend_desc->backend_info[index].flag = flag; ereport(DEBUG1, - (errmsg("setting \"backend_flag%d\" flag: %04x ",index, flag))); + (errmsg("setting \"backend_flag%d\" flag: %04x ", index, flag))); pfree(flags); return true; } -static bool LogDestinationProcessFunc (char* newval, int elevel) +static bool +LogDestinationProcessFunc(char *newval, int elevel) { #ifndef POOL_PRIVATE - char **destinations; - int n,i; - int log_destination = 0; + char **destinations; + int n, + i; + int log_destination = 0; + destinations = get_list_from_string(newval, ",", &n); if (!destinations || n < 0) { @@ -3719,10 +3766,10 @@ static bool LogDestinationProcessFunc (char* newval, int elevel) pfree(destinations); ereport(elevel, - (errmsg("invalid value \"%s\" for log_destination",newval))); + (errmsg("invalid value \"%s\" for log_destination", newval))); return false; } - for (i=0;i<n;i++) + for (i = 0; i < n; i++) { if (!strcmp(destinations[i], "syslog")) { @@ -3734,10 +3781,11 @@ static bool LogDestinationProcessFunc (char* newval, int elevel) } else { - int k; + int k; + ereport(elevel, - (errmsg("invalid configuration for \"log_destination\""), - errdetail("unknown destination :%s", destinations[i]))); + (errmsg("invalid configuration for \"log_destination\""), + errdetail("unknown destination :%s", destinations[i]))); for (k = i; k < n; k++) pfree(destinations[k]); pfree(destinations); @@ -3745,7 +3793,7 @@ static bool LogDestinationProcessFunc (char* newval, int elevel) } pfree(destinations[i]); } - if (g_pool_config.log_destination & LOG_DESTINATION_SYSLOG ) + if (g_pool_config.log_destination & LOG_DESTINATION_SYSLOG) { if (!(log_destination & LOG_DESTINATION_SYSLOG)) closelog(); @@ -3756,19 +3804,21 @@ static bool LogDestinationProcessFunc (char* newval, int elevel) return true; } -static bool SyslogFacilityProcessFunc (int newval, int elevel) +static bool +SyslogFacilityProcessFunc(int newval, int elevel) { #ifndef POOL_PRIVATE #ifdef HAVE_SYSLOG /* set syslog parameters */ set_syslog_parameters(g_pool_config.syslog_ident ? g_pool_config.syslog_ident : "pgpool", - g_pool_config.syslog_facility); + g_pool_config.syslog_facility); #endif #endif return true; } -static bool SyslogIdentProcessFunc (char* newval, int elevel) +static bool +SyslogIdentProcessFunc(char *newval, int elevel) { #ifndef POOL_PRIVATE #ifdef HAVE_SYSLOG @@ -3780,38 +3830,46 @@ static bool SyslogIdentProcessFunc (char* newval, int elevel) return true; } -static const char* IntValueShowFunc(int value) +static const char * +IntValueShowFunc(int value) { static char buffer[10]; - snprintf(buffer, sizeof(buffer), "%d" ,value); + + snprintf(buffer, sizeof(buffer), "%d", value); return buffer; } -static const char* BackendWeightShowFunc(int index) +static const char * +BackendWeightShowFunc(int index) { return IntValueShowFunc(g_pool_config.backend_desc->backend_info[index].unnormalized_weight); } -static const char* BackendPortShowFunc(int index) +static const char * +BackendPortShowFunc(int index) { return IntValueShowFunc(g_pool_config.backend_desc->backend_info[index].backend_port); } -static const char* BackendHostShowFunc(int index) +static const char * +BackendHostShowFunc(int index) { return g_pool_config.backend_desc->backend_info[index].backend_hostname; } -static const char* BackendDataDirShowFunc(int index) +static const char * +BackendDataDirShowFunc(int index) { return g_pool_config.backend_desc->backend_info[index].backend_data_directory; } -static const char* BackendFlagsShowFunc(int index) +static const char * +BackendFlagsShowFunc(int index) { static char buffer[21]; unsigned short flag = g_pool_config.backend_desc->backend_info[index].flag; + if (POOL_ALLOW_TO_FAILOVER(flag)) snprintf(buffer, sizeof(buffer), "ALLOW_TO_FAILOVER"); else if (POOL_DISALLOW_TO_FAILOVER(flag)) @@ -3819,81 +3877,98 @@ static const char* BackendFlagsShowFunc(int index) return buffer; } -static bool BackendSlotEmptyCheckFunc(int index) +static bool +BackendSlotEmptyCheckFunc(int index) { return (g_pool_config.backend_desc->backend_info[index].backend_port == 0); } -static bool WdSlotEmptyCheckFunc(int index) +static bool +WdSlotEmptyCheckFunc(int index) { return (g_pool_config.wd_remote_nodes.wd_remote_node_info[index].pgpool_port == 0); } -static bool WdIFSlotEmptyCheckFunc(int index) +static bool +WdIFSlotEmptyCheckFunc(int index) { - + return (index >= g_pool_config.num_hb_if); } -static const char* OtherPPHostShowFunc(int index) +static const char * +OtherPPHostShowFunc(int index) { return g_pool_config.wd_remote_nodes.wd_remote_node_info[index].hostname; } -static const char* OtherPPPortShowFunc(int index) +static const char * +OtherPPPortShowFunc(int index) { return IntValueShowFunc(g_pool_config.wd_remote_nodes.wd_remote_node_info[index].pgpool_port); } -static const char* OtherWDPortShowFunc(int index) +static const char * +OtherWDPortShowFunc(int index) { return IntValueShowFunc(g_pool_config.wd_remote_nodes.wd_remote_node_info[index].wd_port); } -static const char* HBDeviceShowFunc(int index) +static const char * +HBDeviceShowFunc(int index) { return g_pool_config.hb_if[index].if_name; } -static const char* HBDestinationShowFunc(int index) +static const char * +HBDestinationShowFunc(int index) { return g_pool_config.hb_if[index].addr; } -static const char* HBDestinationPortShowFunc(int index) +static const char * +HBDestinationPortShowFunc(int index) { return IntValueShowFunc(g_pool_config.hb_if[index].dest_port); } -static const char* HealthCheckPeriodShowFunc(int index) +static const char * +HealthCheckPeriodShowFunc(int index) { return IntValueShowFunc(g_pool_config.health_check_params[index].health_check_period); } -static const char* HealthCheckTimeOutShowFunc(int index) +static const char * +HealthCheckTimeOutShowFunc(int index) { return IntValueShowFunc(g_pool_config.health_check_params[index].health_check_timeout); } -static const char* HealthCheckMaxRetriesShowFunc(int index) +static const char * +HealthCheckMaxRetriesShowFunc(int index) { return IntValueShowFunc(g_pool_config.health_check_params[index].health_check_max_retries); } -static const char* HealthCheckRetryDelayShowFunc(int index) +static const char * +HealthCheckRetryDelayShowFunc(int index) { return IntValueShowFunc(g_pool_config.health_check_params[index].health_check_retry_delay); } -static const char* HealthCheckConnectTimeOutShowFunc(int index) +static const char * +HealthCheckConnectTimeOutShowFunc(int index) { return IntValueShowFunc(g_pool_config.health_check_params[index].connect_timeout); } -static const char* HealthCheckUserShowFunc(int index) +static const char * +HealthCheckUserShowFunc(int index) { return g_pool_config.health_check_params[index].health_check_user; } -static const char* HealthCheckPasswordShowFunc(int index) +static const char * +HealthCheckPasswordShowFunc(int index) { return g_pool_config.health_check_params[index].health_check_password; } -static const char* HealthCheckDatabaseShowFunc(int index) +static const char * +HealthCheckDatabaseShowFunc(int index) { return g_pool_config.health_check_params[index].health_check_database; } @@ -3902,37 +3977,47 @@ static const char* HealthCheckDatabaseShowFunc(int index) /* Health check configuration assign functions */ /*health_check_period*/ -static bool HealthCheckPeriodAssignFunc (ConfigContext context, int newval, int index, int elevel) +static bool +HealthCheckPeriodAssignFunc(ConfigContext context, int newval, int index, int elevel) { g_pool_config.health_check_params[index].health_check_period = newval; return true; } + /*health_check_timeout*/ -static bool HealthCheckTimeOutAssignFunc (ConfigContext context, int newval, int index, int elevel) +static bool +HealthCheckTimeOutAssignFunc(ConfigContext context, int newval, int index, int elevel) { g_pool_config.health_check_params[index].health_check_timeout = newval; return true; } + /*health_check_max_retries*/ -static bool HealthCheckMaxRetriesAssignFunc (ConfigContext context, int newval, int index, int elevel) +static bool +HealthCheckMaxRetriesAssignFunc(ConfigContext context, int newval, int index, int elevel) { g_pool_config.health_check_params[index].health_check_max_retries = newval; return true; } + /*health_check_retry_delay*/ -static bool HealthCheckRetryDelayAssignFunc (ConfigContext context, int newval, int index, int elevel) +static bool +HealthCheckRetryDelayAssignFunc(ConfigContext context, int newval, int index, int elevel) { g_pool_config.health_check_params[index].health_check_retry_delay = newval; return true; } + /*connect_timeout*/ -static bool HealthCheckConnectTimeOutAssignFunc (ConfigContext context, int newval, int index, int elevel) +static bool +HealthCheckConnectTimeOutAssignFunc(ConfigContext context, int newval, int index, int elevel) { g_pool_config.health_check_params[index].connect_timeout = newval; return true; } -static bool HealthCheckUserAssignFunc(ConfigContext context, char* newval, int index, int elevel) +static bool +HealthCheckUserAssignFunc(ConfigContext context, char *newval, int index, int elevel) { if (g_pool_config.health_check_params[index].health_check_user) pfree(g_pool_config.health_check_params[index].health_check_user); @@ -3943,7 +4028,8 @@ static bool HealthCheckUserAssignFunc(ConfigContext context, char* newval, int i return true; } -static bool HealthCheckPasswordAssignFunc(ConfigContext context, char* newval, int index, int elevel) +static bool +HealthCheckPasswordAssignFunc(ConfigContext context, char *newval, int index, int elevel) { if (g_pool_config.health_check_params[index].health_check_password) pfree(g_pool_config.health_check_params[index].health_check_password); @@ -3954,7 +4040,8 @@ static bool HealthCheckPasswordAssignFunc(ConfigContext context, char* newval, i return true; } -static bool HealthCheckDatabaseAssignFunc(ConfigContext context, char* newval, int index, int elevel) +static bool +HealthCheckDatabaseAssignFunc(ConfigContext context, char *newval, int index, int elevel) { if (g_pool_config.health_check_params[index].health_check_database) pfree(g_pool_config.health_check_params[index].health_check_database); @@ -3968,31 +4055,35 @@ static bool HealthCheckDatabaseAssignFunc(ConfigContext context, char* newval, i /* Watchdog Assign functions */ /*other_pgpool_hostname*/ -static bool OtherPPHostAssignFunc (ConfigContext context, char* newval, int index, int elevel) +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); + 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) +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) +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) +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'; @@ -4002,17 +4093,19 @@ static bool HBDeviceAssignFunc (ConfigContext context, char* newval, int index, } /*heartbeat_destination*/ -static bool HBDestinationAssignFunc (ConfigContext context, char* newval, int index, int elevel) +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); + 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) +static bool +HBDestinationPortAssignFunc(ConfigContext context, int newval, int index, int elevel) { g_pool_config.hb_if[index].dest_port = newval; return true; @@ -4022,60 +4115,63 @@ static bool HBDestinationPortAssignFunc (ConfigContext context, int newval, int * 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) +static bool +check_redirect_node_spec(char *node_spec) { - int len = strlen(node_spec); - int i; - int64 val; - + 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++) + for (i = 0; i < len; i++) { - if (!isdigit((int)node_spec[i])) + if (!isdigit((int) node_spec[i])) return false; } val = pool_atoi64(node_spec); - - if (val >=0 && val < MAX_NUM_BACKENDS) + + if (val >= 0 && val < MAX_NUM_BACKENDS) return true; return false; } -static bool config_post_processor(ConfigContext context, int elevel) +static bool +config_post_processor(ConfigContext context, int elevel) { - double total_weight = 0.0; + double total_weight = 0.0; sig_atomic_t local_num_backends = 0; - int i; + int i; if (context == CFGCXT_BOOT) { - char localhostname[256]; - int res = gethostname(localhostname,sizeof(localhostname)); - if(res !=0 ) + char localhostname[256]; + int res = gethostname(localhostname, sizeof(localhostname)); + + if (res != 0) { ereport(WARNING, - (errmsg("initializing pool configuration"), + (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++) + for (i = 0; i < MAX_CONNECTION_SLOTS; i++) { BackendInfo *backend_info = &g_pool_config.backend_desc->backend_info[i]; @@ -4089,13 +4185,13 @@ static bool config_post_processor(ConfigContext context, int elevel) else { total_weight += backend_info->unnormalized_weight; - local_num_backends = i+1; - + 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"), + (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); @@ -4107,42 +4203,44 @@ static bool config_post_processor(ConfigContext context, int elevel) pool_config->backend_desc->num_backends = local_num_backends; ereport(DEBUG1, - (errmsg("initializing pool configuration"), + (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. + * 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++) + 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; + (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))); + 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++ ) + for (i = 0; i < MAX_WATCHDOG_NUM; i++) { - WdRemoteNodeInfo* wdNode = &g_pool_config.wd_remote_nodes.wd_remote_node_info[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++ ) + 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; @@ -4152,7 +4250,7 @@ static bool config_post_processor(ConfigContext context, int elevel) if (strcmp(pool_config->recovery_1st_stage_command, "") || strcmp(pool_config->recovery_2nd_stage_command, "")) { - for (i=0;i<MAX_CONNECTION_SLOTS;i++) + for (i = 0; i < MAX_CONNECTION_SLOTS; i++) { BackendInfo *backend_info = &g_pool_config.backend_desc->backend_info[i]; @@ -4169,26 +4267,27 @@ static bool config_post_processor(ConfigContext context, int elevel) return true; } -static bool MakeAppRedirectListRegex (char* newval, int elevel) +static bool +MakeAppRedirectListRegex(char *newval, int elevel) { /* TODO Deal with the memory */ - int i; + 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++) + + for (i = 0; i < lrtokens->pos; i++) { if (!check_redirect_node_spec(lrtokens->token[i].right_token)) { @@ -4197,8 +4296,8 @@ static bool MakeAppRedirectListRegex (char* newval, int elevel) 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)) { @@ -4208,43 +4307,45 @@ static bool MakeAppRedirectListRegex (char* newval, int elevel) return false; } } - + return true; } -static bool MakeDBRedirectListRegex (char* newval, int elevel) +static bool +MakeDBRedirectListRegex(char *newval, int elevel) { /* TODO Deal with the memory */ - int i; + 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++) + + for (i = 0; i < lrtokens->pos; i++) { if (!check_redirect_node_spec(lrtokens->token[i].right_token)) { ereport(elevel, - (errmsg("invalid configuration for key \"database_redirect_preference_list\""), + (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(elevel, - (errmsg("invalid configuration for key \"database_redirect_preference_list\""), + (errmsg("invalid configuration for key \"database_redirect_preference_list\""), errdetail("wrong redirect dbname regular expression: \"%s\"", lrtokens->token[i].left_token))); return false; } @@ -4252,35 +4353,38 @@ static bool MakeDBRedirectListRegex (char* newval, int elevel) return true; } -static struct config_generic* -get_index_free_record_if_any(struct config_generic* record) +static struct config_generic * +get_index_free_record_if_any(struct config_generic *record) { - struct config_generic* ret = NULL; + struct config_generic *ret = NULL; switch (record->vartype) { case CONFIG_VAR_TYPE_INT_ARRAY: - { - struct config_int_array *conf = (struct config_int_array *) record; - if (conf->config_no_index.gen.name) - ret = (struct config_generic*)&conf->config_no_index; - } + { + struct config_int_array *conf = (struct config_int_array *) record; + + if (conf->config_no_index.gen.name) + ret = (struct config_generic *) &conf->config_no_index; + } break; case CONFIG_VAR_TYPE_DOUBLE_ARRAY: - { - struct config_double_array *conf = (struct config_double_array *) record; - if (conf->config_no_index.gen.name) - ret = (struct config_generic*)&conf->config_no_index; - } + { + struct config_double_array *conf = (struct config_double_array *) record; + + if (conf->config_no_index.gen.name) + ret = (struct config_generic *) &conf->config_no_index; + } break; case CONFIG_VAR_TYPE_STRING_ARRAY: - { - struct config_string_array *conf = (struct config_string_array *) record; - if (conf->config_no_index.gen.name) - ret = (struct config_generic*)&conf->config_no_index; - } + { + struct config_string_array *conf = (struct config_string_array *) record; + + if (conf->config_no_index.gen.name) + ret = (struct config_generic *) &conf->config_no_index; + } break; default: break; @@ -4296,7 +4400,7 @@ get_index_free_record_if_any(struct config_generic* record) * allocated for modification. */ static const char * -config_enum_lookup_by_value(struct config_enum * record, int val) +config_enum_lookup_by_value(struct config_enum *record, int val) { const struct config_enum_entry *entry; @@ -4305,18 +4409,18 @@ config_enum_lookup_by_value(struct config_enum * record, int val) if (entry->val == val) return entry->name; } - /* should never happen*/ + /* should never happen */ return NULL; } static char * -ShowOption(struct config_generic * record, int index, int elevel) +ShowOption(struct config_generic *record, int index, int elevel) { char buffer[256]; const char *val; - - /* if the value needs to be hidden - * no need to dig further + + /* + * if the value needs to be hidden no need to dig further */ if (record->flags & VAR_HIDDEN_VALUE) return pstrdup("*****"); @@ -4324,178 +4428,182 @@ ShowOption(struct config_generic * record, int index, int elevel) switch (record->vartype) { case CONFIG_VAR_TYPE_BOOL: - { - struct config_bool *conf = (struct config_bool *) record; - - if (conf->show_hook) - val = (*conf->show_hook) (); - else - val = *conf->variable ? "on" : "off"; - } + { + struct config_bool *conf = (struct config_bool *) record; + + if (conf->show_hook) + val = (*conf->show_hook) (); + else + val = *conf->variable ? "on" : "off"; + } break; - + case CONFIG_VAR_TYPE_INT: - { - struct config_int *conf = (struct config_int *) record; - - if (conf->show_hook) - val = (*conf->show_hook) (); - else { - int result = *conf->variable; - snprintf(buffer, sizeof(buffer), "%d" , - result); - val = buffer; + struct config_int *conf = (struct config_int *) record; + + if (conf->show_hook) + val = (*conf->show_hook) (); + else + { + int result = *conf->variable; + + snprintf(buffer, sizeof(buffer), "%d", + result); + val = buffer; + } } - } break; case CONFIG_VAR_TYPE_LONG: - { - struct config_long *conf = (struct config_long *) record; - - if (conf->show_hook) - val = (*conf->show_hook) (); - else { - int64 result = (int64)*conf->variable; - snprintf(buffer, sizeof(buffer), INT64_FORMAT , - result); - val = buffer; + struct config_long *conf = (struct config_long *) record; + + if (conf->show_hook) + val = (*conf->show_hook) (); + else + { + int64 result = (int64) *conf->variable; + + snprintf(buffer, sizeof(buffer), INT64_FORMAT, + result); + val = buffer; + } } - } break; - + case CONFIG_VAR_TYPE_DOUBLE: - { - struct config_double *conf = (struct config_double *) record; - - if (conf->show_hook) - val = (*conf->show_hook)(); - else { - snprintf(buffer, sizeof(buffer), "%g", - *conf->variable); - val = buffer; + struct config_double *conf = (struct config_double *) record; + + if (conf->show_hook) + val = (*conf->show_hook) (); + else + { + snprintf(buffer, sizeof(buffer), "%g", + *conf->variable); + val = buffer; + } } - } break; - + case CONFIG_VAR_TYPE_STRING: - { - struct config_string *conf = (struct config_string *) record; - - if (conf->show_hook) - val = (*conf->show_hook) (); - else if (*conf->variable && **conf->variable) - val = *conf->variable; - else - val = ""; - } + { + struct config_string *conf = (struct config_string *) record; + + if (conf->show_hook) + val = (*conf->show_hook) (); + else if (*conf->variable && **conf->variable) + val = *conf->variable; + else + val = ""; + } break; - + case CONFIG_VAR_TYPE_ENUM: - { - struct config_enum *conf = (struct config_enum *) record; - - if (conf->show_hook) - val = (*conf->show_hook) (); - else - val = config_enum_lookup_by_value(conf, *conf->variable); - } + { + struct config_enum *conf = (struct config_enum *) record; + + if (conf->show_hook) + val = (*conf->show_hook) (); + else + val = config_enum_lookup_by_value(conf, *conf->variable); + } break; case CONFIG_VAR_TYPE_INT_ARRAY: - { - struct config_int_array *conf = (struct config_int_array *) record; - - if (index >= record->max_elements || index < 0) { - ereport(elevel, - (errmsg("invalid index %d for configuration parameter \"%s\"",index, conf->gen.name), - errdetail("allowed index is between 0 and %d",record->max_elements -1))); + struct config_int_array *conf = (struct config_int_array *) record; - val = NULL; - } - else - { - if (conf->show_hook) - val = (*conf->show_hook) (index); + if (index >= record->max_elements || index < 0) + { + ereport(elevel, + (errmsg("invalid index %d for configuration parameter \"%s\"", index, conf->gen.name), + errdetail("allowed index is between 0 and %d", record->max_elements - 1))); + + val = NULL; + } else { - int result = *conf->variable[index]; - snprintf(buffer, sizeof(buffer), "%d" , - result); - val = buffer; + if (conf->show_hook) + val = (*conf->show_hook) (index); + else + { + int result = *conf->variable[index]; + + snprintf(buffer, sizeof(buffer), "%d", + result); + val = buffer; + } } } - } break; case CONFIG_VAR_TYPE_DOUBLE_ARRAY: - { - struct config_double_array *conf = (struct config_double_array *) record; - - if (index >= record->max_elements || index < 0) - { - ereport(elevel, - (errmsg("invalid index %d for configuration parameter \"%s\"",index, conf->gen.name), - errdetail("allowed index is between 0 and %d",record->max_elements -1))); - - val = NULL; - } - else { - if (conf->show_hook) - val = (*conf->show_hook) (index); + struct config_double_array *conf = (struct config_double_array *) record; + + if (index >= record->max_elements || index < 0) + { + ereport(elevel, + (errmsg("invalid index %d for configuration parameter \"%s\"", index, conf->gen.name), + errdetail("allowed index is between 0 and %d", record->max_elements - 1))); + + val = NULL; + } else { - double result = *conf->variable[index]; - snprintf(buffer, sizeof(buffer), "%g" , - result); - val = buffer; + if (conf->show_hook) + val = (*conf->show_hook) (index); + else + { + double result = *conf->variable[index]; + + snprintf(buffer, sizeof(buffer), "%g", + result); + val = buffer; + } } } - } break; case CONFIG_VAR_TYPE_STRING_ARRAY: - { - struct config_string_array *conf = (struct config_string_array *) record; - - if (index >= record->max_elements || index < 0) { - ereport(elevel, - (errmsg("invalid index %d for configuration parameter \"%s\"",index, conf->gen.name), - errdetail("allowed index is between 0 and %d",record->max_elements -1))); - - val = NULL; + struct config_string_array *conf = (struct config_string_array *) record; + + if (index >= record->max_elements || index < 0) + { + ereport(elevel, + (errmsg("invalid index %d for configuration parameter \"%s\"", index, conf->gen.name), + errdetail("allowed index is between 0 and %d", record->max_elements - 1))); + + val = NULL; + } + else + { + if (conf->show_hook) + val = (*conf->show_hook) (index); + else if ((*conf->variable)[index] && ***conf->variable) + val = (*conf->variable)[index]; + else + val = ""; + } } - else + break; + case CONFIG_VAR_TYPE_STRING_LIST: { + struct config_string_list *conf = (struct config_string_list *) record; + if (conf->show_hook) - val = (*conf->show_hook) (index); - else if ( (*conf->variable)[index] && ***conf->variable) - val = (*conf->variable)[index]; + val = (*conf->show_hook) (); + else if (conf->current_val) + val = conf->current_val; else val = ""; } - } break; - case CONFIG_VAR_TYPE_STRING_LIST: - { - struct config_string_list *conf = (struct config_string_list *) record; - - if (conf->show_hook) - val = (*conf->show_hook) (); - else if (conf->current_val) - val = conf->current_val; - else - val = ""; - } - break; - + default: /* just to keep compiler quiet */ val = "???"; @@ -4507,7 +4615,8 @@ ShowOption(struct config_generic * record, int index, int elevel) } -static bool value_slot_for_config_record_is_empty(struct config_generic* record, int index) +static bool +value_slot_for_config_record_is_empty(struct config_generic *record, int index) { switch (record->vartype) { @@ -4519,41 +4628,46 @@ static bool value_slot_for_config_record_is_empty(struct config_generic* record, case CONFIG_VAR_TYPE_ENUM: return false; break; - + case CONFIG_VAR_TYPE_INT_ARRAY: - { - struct config_int_array *conf = (struct config_int_array *) record; - if (conf->empty_slot_check_func) - return (*conf->empty_slot_check_func)(index); - } + { + struct config_int_array *conf = (struct config_int_array *) record; + + if (conf->empty_slot_check_func) + return (*conf->empty_slot_check_func) (index); + } break; - + case CONFIG_VAR_TYPE_DOUBLE_ARRAY: - { - struct config_double_array *conf = (struct config_double_array *) record; - if (conf->empty_slot_check_func) - return (*conf->empty_slot_check_func)(index); - } + { + struct config_double_array *conf = (struct config_double_array *) record; + + if (conf->empty_slot_check_func) + return (*conf->empty_slot_check_func) (index); + } break; - + case CONFIG_VAR_TYPE_STRING_ARRAY: - { - struct config_string_array *conf = (struct config_string_array *) record; - if (conf->empty_slot_check_func) - return (*conf->empty_slot_check_func)(index); - } + { + struct config_string_array *conf = (struct config_string_array *) record; + + if (conf->empty_slot_check_func) + return (*conf->empty_slot_check_func) (index); + } break; - + default: break; } return false; } -bool set_config_option_for_session(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *name, const char *value) +bool +set_config_option_for_session(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value) { - bool ret; + bool ret; MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); + ret = set_one_config_option(name, value, CFGCXT_SESSION, PGC_S_SESSION, FRONTEND_ONLY_ERROR); if (ret == true) { @@ -4563,18 +4677,19 @@ bool set_config_option_for_session(POOL_CONNECTION *frontend, POOL_CONNECTION_PO return ret; } -bool reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +bool +reset_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - int i; - int elevel = (frontend == NULL)?FATAL:FRONTEND_ONLY_ERROR; + int i; + int elevel = (frontend == NULL) ? FATAL : FRONTEND_ONLY_ERROR; MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); ereport(DEBUG2, - (errmsg("RESET ALL CONFIG VARIABLES"))); + (errmsg("RESET ALL CONFIG VARIABLES"))); for (i = 0; i < num_all_parameters; ++i) { - struct config_generic* record = all_parameters[i]; + struct config_generic *record = all_parameters[i]; /* Don't reset if special exclusion from RESET ALL */ if (record->flags & VAR_NO_RESET_ALL) @@ -4582,13 +4697,14 @@ bool reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen if (record->dynamic_array_var) { - int index; + int index; + for (index = 0; index < record->max_elements; index++) { if (record->scontexts[index] != CFGCXT_SESSION) continue; - if (value_slot_for_config_record_is_empty(record,index)) + if (value_slot_for_config_record_is_empty(record, index)) continue; setConfigOptionVar(record, record->name, index, NULL, @@ -4598,7 +4714,8 @@ bool reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen /* Also set the default value for index free record if any */ if (record->flags & ARRAY_VAR_ALLOW_NO_INDEX) { - struct config_generic* idx_free_record = get_index_free_record_if_any(record); + struct config_generic *idx_free_record = get_index_free_record_if_any(record); + if (idx_free_record && idx_free_record->scontexts[0] == CFGCXT_SESSION) { ereport(DEBUG1, @@ -4626,21 +4743,23 @@ bool reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen return true; } -bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +bool +report_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - int i; - int num_rows = 0; - const char* value; + int i; + int num_rows = 0; + const char *value; send_row_description_for_detail_view(frontend, backend); /* - * grouped variables are not listed in all parameter array - * so start with group variables. + * grouped variables are not listed in all parameter array so start with + * group variables. */ for (i = 0; ConfigureVarGroups[i].gen.name; i++) { - int rows = send_grouped_type_variable_to_frontend(&ConfigureVarGroups[i], frontend, backend); + int rows = send_grouped_type_variable_to_frontend(&ConfigureVarGroups[i], frontend, backend); + if (rows < 0) return false; num_rows += rows; @@ -4648,7 +4767,8 @@ bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe for (i = 0; i < num_all_parameters; ++i) { - struct config_generic* record = all_parameters[i]; + struct config_generic *record = all_parameters[i]; + if (record->flags & VAR_PART_OF_GROUP) continue; @@ -4657,7 +4777,8 @@ bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe if (record->dynamic_array_var) { - int rows = send_array_type_variable_to_frontend(record, frontend, backend); + int rows = send_array_type_variable_to_frontend(record, frontend, backend); + if (rows < 0) return false; num_rows += rows; @@ -4669,7 +4790,7 @@ bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe if (value == NULL) return false; send_config_var_detail_row(frontend, backend, record->name, value, record->description); - pfree((void*)value); + pfree((void *) value); num_rows++; } } @@ -4678,25 +4799,27 @@ bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe } -bool report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* var_name) +bool +report_config_variable(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *var_name) { - int index = 0; - char *value; - int num_rows = 0; - struct config_generic* record; + int index = 0; + char *value; + int num_rows = 0; + struct config_generic *record; - if ( strcmp(var_name,"all") == 0) - return report_all_variables(frontend,backend); + if (strcmp(var_name, "all") == 0) + return report_all_variables(frontend, backend); /* search the variable */ record = find_option(var_name, WARNING); if (record == NULL) { - int i; + int i; + /* check if the var name match the grouped var */ for (i = 0; ConfigureVarGroups[i].gen.name; i++) { - if (strcmp(ConfigureVarGroups[i].gen.name,var_name) == 0) + if (strcmp(ConfigureVarGroups[i].gen.name, var_name) == 0) { send_row_description_for_detail_view(frontend, backend); num_rows = send_grouped_type_variable_to_frontend(&ConfigureVarGroups[i], frontend, backend); @@ -4708,7 +4831,7 @@ bool report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac } ereport(FRONTEND_ONLY_ERROR, - (errmsg("config variable \"%s\" not found",var_name))); + (errmsg("config variable \"%s\" not found", var_name))); return false; } @@ -4720,10 +4843,12 @@ bool report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (index < 0) { - /* Index is not included in parameter name. - * this is the multi value config variable */ + /* + * Index is not included in parameter name. this is the multi + * value config variable + */ ereport(DEBUG3, - (errmsg("show parameter \"%s\" with out index",var_name))); + (errmsg("show parameter \"%s\" with out index", var_name))); send_row_description_for_detail_view(frontend, backend); num_rows = send_array_type_variable_to_frontend(record, frontend, backend); if (num_rows < 0) @@ -4735,29 +4860,30 @@ bool report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac { /* single value only */ num_rows = 1; - send_row_description(frontend, backend, 1, (char**)&var_name); + send_row_description(frontend, backend, 1, (char **) &var_name); value = ShowOption(record, index, FRONTEND_ONLY_ERROR); if (value == NULL) return false; send_config_var_value_only_row(frontend, backend, value); - pfree((void*)value); + pfree((void *) value); } - send_complete_and_ready(frontend, backend, "SELECT" ,num_rows); + send_complete_and_ready(frontend, backend, "SELECT", num_rows); return true; } -static int send_array_type_variable_to_frontend(struct config_generic* record, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +static int +send_array_type_variable_to_frontend(struct config_generic *record, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { if (record->dynamic_array_var) { - const int MAX_NAME_LEN = 255; - char name[MAX_NAME_LEN +1]; - int index; - int num_rows = 0; + const int MAX_NAME_LEN = 255; + char name[MAX_NAME_LEN + 1]; + int index; + int num_rows = 0; const char *value; - struct config_generic* idx_free_record = get_index_free_record_if_any(record); + struct config_generic *idx_free_record = get_index_free_record_if_any(record); /* Before printing the array, print the index free value if any */ if (idx_free_record) @@ -4765,47 +4891,50 @@ static int send_array_type_variable_to_frontend(struct config_generic* record, P value = ShowOption(idx_free_record, 0, FRONTEND_ONLY_ERROR); if (value) { - send_config_var_detail_row(frontend, backend, (const char*)idx_free_record->name, value, record->description); - pfree((void*)value); + send_config_var_detail_row(frontend, backend, (const char *) idx_free_record->name, value, record->description); + pfree((void *) value); num_rows++; } } for (index = 0; index < record->max_elements; index++) { - if (value_slot_for_config_record_is_empty(record,index)) + if (value_slot_for_config_record_is_empty(record, index)) continue; /* construct the name with index */ - snprintf(name, MAX_NAME_LEN, "%s%d",record->name,index); + snprintf(name, MAX_NAME_LEN, "%s%d", record->name, index); value = ShowOption(record, index, FRONTEND_ONLY_ERROR); if (value == NULL) return -1; - send_config_var_detail_row(frontend, backend, (const char*)name, value, record->description); - pfree((void*)value); + send_config_var_detail_row(frontend, backend, (const char *) name, value, record->description); + pfree((void *) value); num_rows++; } return num_rows; } - return -1; /* error */ + return -1; /* error */ } -static int send_grouped_type_variable_to_frontend(struct config_grouped_array_var* grouped_record, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +static int +send_grouped_type_variable_to_frontend(struct config_grouped_array_var *grouped_record, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - int k,index; - int max_elements = grouped_record->var_list[0]->max_elements; - int num_rows = 0; + int k, + index; + int max_elements = grouped_record->var_list[0]->max_elements; + int num_rows = 0; const char *value; - for (k =0; k < grouped_record->var_count; k++) + for (k = 0; k < grouped_record->var_count; k++) { - struct config_generic* record = grouped_record->var_list[k]; - struct config_generic* idx_free_record = get_index_free_record_if_any(record); + struct config_generic *record = grouped_record->var_list[k]; + struct config_generic *idx_free_record = get_index_free_record_if_any(record); + if (idx_free_record) { value = ShowOption(idx_free_record, 0, FRONTEND_ONLY_ERROR); if (value) { - send_config_var_detail_row(frontend, backend, (const char*)idx_free_record->name, value, record->description); - pfree((void*)value); + send_config_var_detail_row(frontend, backend, (const char *) idx_free_record->name, value, record->description); + pfree((void *) value); num_rows++; } } @@ -4813,22 +4942,22 @@ static int send_grouped_type_variable_to_frontend(struct config_grouped_array_va for (index = 0; index < max_elements; index++) { - for (k =0; k < grouped_record->var_count; k++) + for (k = 0; k < grouped_record->var_count; k++) { - const int MAX_NAME_LEN = 255; - char name[MAX_NAME_LEN +1]; + const int MAX_NAME_LEN = 255; + char name[MAX_NAME_LEN + 1]; - struct config_generic* record = grouped_record->var_list[k]; + struct config_generic *record = grouped_record->var_list[k]; - if (value_slot_for_config_record_is_empty(record,index)) + if (value_slot_for_config_record_is_empty(record, index)) break; /* construct the name with index */ - snprintf(name, MAX_NAME_LEN, "%s%d",record->name,index); - value = ShowOption(record, index,FRONTEND_ONLY_ERROR); + snprintf(name, MAX_NAME_LEN, "%s%d", record->name, index); + value = ShowOption(record, index, FRONTEND_ONLY_ERROR); if (value == NULL) return -1; - send_config_var_detail_row(frontend, backend, (const char*)name, value, record->description); - pfree((void*)value); + send_config_var_detail_row(frontend, backend, (const char *) name, value, record->description); + pfree((void *) value); num_rows++; } } @@ -4836,9 +4965,11 @@ static int send_grouped_type_variable_to_frontend(struct config_grouped_array_va return num_rows; } -static void send_row_description_for_detail_view(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +static void +send_row_description_for_detail_view(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { static char *field_names[] = {"item", "value", "description"}; + send_row_description(frontend, backend, 3, field_names); } -#endif /* not defined POOL_FRONTEND*/ +#endif /* not defined POOL_FRONTEND */ diff --git a/src/context/pool_process_context.c b/src/context/pool_process_context.c index 25de937b8..baa4d7090 100644 --- a/src/context/pool_process_context.c +++ b/src/context/pool_process_context.c @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2017 PgPool Global Development Group @@ -29,31 +29,33 @@ #include "pool_config.h" /* remove me afterwards */ static POOL_PROCESS_CONTEXT process_context_d; -static POOL_PROCESS_CONTEXT *process_context; +static POOL_PROCESS_CONTEXT * process_context; /* * Initialize per process context */ -void pool_init_process_context(void) +void +pool_init_process_context(void) { process_context = &process_context_d; if (!process_info) ereport(FATAL, - (return_code(1), + (return_code(1), errmsg("process info is not set"))); process_context->process_info = process_info; if (!pool_config->backend_desc) ereport(FATAL, - (return_code(1), + (return_code(1), errmsg("backend desc is not set"))); process_context->backend_desc = pool_config->backend_desc; process_context->proc_id = my_proc_id; - process_context->local_session_id = 0; /* initialize local session counter */ + process_context->local_session_id = 0; /* initialize local session + * counter */ process_context->last_alarm_handler = SIG_IGN; process_context->last_alarm_time = 0; @@ -64,7 +66,8 @@ void pool_init_process_context(void) /* * Return process context */ -POOL_PROCESS_CONTEXT *pool_get_process_context(void) +POOL_PROCESS_CONTEXT * +pool_get_process_context(void) { return process_context; } @@ -72,11 +75,12 @@ POOL_PROCESS_CONTEXT *pool_get_process_context(void) /* * Return my process info */ -ProcessInfo *pool_get_my_process_info(void) +ProcessInfo * +pool_get_my_process_info(void) { if (!process_context) ereport(FATAL, - (return_code(1), + (return_code(1), errmsg("process context is not initialized"))); return &process_context->process_info[process_context->proc_id]; @@ -85,7 +89,8 @@ ProcessInfo *pool_get_my_process_info(void) /* * Increment local session id */ -void pool_incremnet_local_session_id(void) +void +pool_incremnet_local_session_id(void) { POOL_PROCESS_CONTEXT *p = pool_get_process_context(); @@ -99,9 +104,11 @@ void pool_incremnet_local_session_id(void) /* * Return byte size of connection info(ConnectionInfo) on shmem. */ -int pool_coninfo_size(void) +int +pool_coninfo_size(void) { - int size; + int size; + size = pool_config->num_init_children * pool_config->max_pool * MAX_NUM_BACKENDS * @@ -120,9 +127,11 @@ int pool_coninfo_size(void) /* * Return number of elements of connection info(ConnectionInfo) on shmem. */ -int pool_coninfo_num(void) +int +pool_coninfo_num(void) { - int nelm; + int nelm; + nelm = pool_config->num_init_children * pool_config->max_pool * MAX_NUM_BACKENDS; @@ -134,12 +143,13 @@ int pool_coninfo_num(void) * Return pointer to i th child, j th connection pool and k th backend * of connection info on shmem. */ -ConnectionInfo *pool_coninfo(int child, int connection_pool, int backend) +ConnectionInfo * +pool_coninfo(int child, int connection_pool, int backend) { if (child < 0 || child >= pool_config->num_init_children) { ereport(WARNING, - (errmsg("failed to get connection info, invalid child number: %d", child))); + (errmsg("failed to get connection info, invalid child number: %d", child))); return NULL; } @@ -157,8 +167,8 @@ ConnectionInfo *pool_coninfo(int child, int connection_pool, int backend) return NULL; } - return &con_info[child*pool_config->max_pool*MAX_NUM_BACKENDS+ - connection_pool*MAX_NUM_BACKENDS+ + return &con_info[child * pool_config->max_pool * MAX_NUM_BACKENDS + + connection_pool * MAX_NUM_BACKENDS + backend]; } @@ -166,10 +176,11 @@ ConnectionInfo *pool_coninfo(int child, int connection_pool, int backend) * Return pointer to child which has OS process id pid, j th connection * pool and k th backend of connection info on shmem. */ -ConnectionInfo *pool_coninfo_pid(int pid, int connection_pool, int backend) +ConnectionInfo * +pool_coninfo_pid(int pid, int connection_pool, int backend) { - int child = -1; - int i; + int child = -1; + int i; for (i = 0; i < pool_config->num_init_children; i++) { @@ -181,19 +192,19 @@ ConnectionInfo *pool_coninfo_pid(int pid, int connection_pool, int backend) } if (child < 0) - elog(ERROR,"failed to get child pid, invalid child PID:%d",pid); + elog(ERROR, "failed to get child pid, invalid child PID:%d", pid); if (child < 0 || child >= pool_config->num_init_children) - elog(ERROR,"failed to get child pid, invalid child no:%d",child); + elog(ERROR, "failed to get child pid, invalid child no:%d", child); if (connection_pool < 0 || connection_pool >= pool_config->max_pool) - elog(ERROR,"failed to get child pid, invalid connection pool no:%d",connection_pool); + elog(ERROR, "failed to get child pid, invalid connection pool no:%d", connection_pool); if (backend < 0 || backend >= MAX_NUM_BACKENDS) - elog(ERROR,"failed to get child pid, invalid backend no:%d",backend); + elog(ERROR, "failed to get child pid, invalid backend no:%d", backend); - return &con_info[child*pool_config->max_pool*MAX_NUM_BACKENDS+ - connection_pool*MAX_NUM_BACKENDS+ + return &con_info[child * pool_config->max_pool * MAX_NUM_BACKENDS + + connection_pool * MAX_NUM_BACKENDS + backend]; } @@ -203,32 +214,35 @@ ConnectionInfo *pool_coninfo_pid(int pid, int connection_pool, int backend) * if the connection is found the *backend_node_id contains the backend node id * of the backend node that has the connection */ -ConnectionInfo* pool_coninfo_backend_pid(int backend_pid, int* backend_node_id) +ConnectionInfo * +pool_coninfo_backend_pid(int backend_pid, int *backend_node_id) { - int child; + int child; + /* - * look for the child process that has the backend - * with the pid + * look for the child process that has the backend with the pid */ ereport(DEBUG1, - (errmsg("searching for the connection with backend pid:%d",backend_pid))); + (errmsg("searching for the connection with backend pid:%d", backend_pid))); for (child = 0; child < pool_config->num_init_children; child++) { - int pool; + int pool; ProcessInfo *pi = pool_get_process_info(process_info[child].pid); for (pool = 0; pool < pool_config->max_pool; pool++) { - int backend_id; + int backend_id; + for (backend_id = 0; backend_id < NUM_BACKENDS; backend_id++) { - int poolBE = pool*MAX_NUM_BACKENDS+backend_id; + int poolBE = pool * MAX_NUM_BACKENDS + backend_id; + if (ntohl(pi->connection_info[poolBE].pid) == backend_pid) { ereport(DEBUG1, - (errmsg("found for the connection with backend pid:%d on backend node %d",backend_pid,backend_id))); + (errmsg("found for the connection with backend pid:%d on backend node %d", backend_pid, backend_id))); *backend_node_id = backend_id; return &pi->connection_info[poolBE]; } @@ -243,12 +257,14 @@ ConnectionInfo* pool_coninfo_backend_pid(int backend_pid, int* backend_node_id) * backend and it should not be considered as a backend node failure. * This flag is used to handle pg_terminate_backend() */ -void pool_set_connection_will_be_terminated(ConnectionInfo* connInfo) +void +pool_set_connection_will_be_terminated(ConnectionInfo * connInfo) { connInfo->swallow_termination = 1; } -void pool_unset_connection_will_be_terminated(ConnectionInfo* connInfo) +void +pool_unset_connection_will_be_terminated(ConnectionInfo * connInfo) { connInfo->swallow_termination = 0; } @@ -256,12 +272,13 @@ void pool_unset_connection_will_be_terminated(ConnectionInfo* connInfo) /* * Set frontend connected flag */ -void pool_coninfo_set_frontend_connected(int proc_id, int pool_index) +void +pool_coninfo_set_frontend_connected(int proc_id, int pool_index) { ConnectionInfo *con; - int i; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -270,7 +287,7 @@ void pool_coninfo_set_frontend_connected(int proc_id, int pool_index) if (con == NULL) { - elog(WARNING,"failed to get connection info while marking the frontend is connected for pool"); + elog(WARNING, "failed to get connection info while marking the frontend is connected for pool"); return; } con->connected = true; @@ -280,12 +297,13 @@ void pool_coninfo_set_frontend_connected(int proc_id, int pool_index) /* * Unset frontend connected flag */ -void pool_coninfo_unset_frontend_connected(int proc_id, int pool_index) +void +pool_coninfo_unset_frontend_connected(int proc_id, int pool_index) { ConnectionInfo *con; - int i; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -294,7 +312,7 @@ void pool_coninfo_unset_frontend_connected(int proc_id, int pool_index) if (con == NULL) { - elog(WARNING,"failed to get connection info while marking the frontend is not connected for pool"); + elog(WARNING, "failed to get connection info while marking the frontend is not connected for pool"); return; } con->connected = false; @@ -306,10 +324,11 @@ void pool_coninfo_unset_frontend_connected(int proc_id, int pool_index) * For pool_alarm_undo(), the alarm second and the old handler * are saved, and the remaining time is calculated. */ -void pool_alarm(pool_sighandler_t handler, unsigned int second) +void +pool_alarm(pool_sighandler_t handler, unsigned int second) { POOL_PROCESS_CONTEXT *p = pool_get_process_context(); - time_t now = time(NULL); + time_t now = time(NULL); alarm(second); p->last_alarm_handler = pool_signal(SIGALRM, handler); @@ -318,7 +337,7 @@ void pool_alarm(pool_sighandler_t handler, unsigned int second) { p->undo_alarm_second = p->last_alarm_second - (now - p->last_alarm_time); if (p->undo_alarm_second <= 0) - p->undo_alarm_second = 1; + p->undo_alarm_second = 1; } p->last_alarm_time = now; @@ -328,7 +347,8 @@ void pool_alarm(pool_sighandler_t handler, unsigned int second) /* * Undo the alarm signal handler using the remaining time. */ -void pool_undo_alarm(void) +void +pool_undo_alarm(void) { POOL_PROCESS_CONTEXT *p = pool_get_process_context(); diff --git a/src/context/pool_query_context.c b/src/context/pool_query_context.c index 0d4a7eb56..1d5ed1975 100644 --- a/src/context/pool_query_context.c +++ b/src/context/pool_query_context.c @@ -37,12 +37,13 @@ /* * Where to send query */ -typedef enum { +typedef enum +{ POOL_PRIMARY, POOL_STANDBY, POOL_EITHER, POOL_BOTH -} POOL_DEST; +} POOL_DEST; #define CHECK_QUERY_CONTEXT_IS_VALID \ do { \ @@ -52,22 +53,24 @@ typedef enum { } while (0) static POOL_DEST send_to_where(Node *node, char *query); -static void where_to_send_deallocate(POOL_QUERY_CONTEXT *query_context, Node *node); -static char* remove_read_write(int len, const char *contents, int *rewritten_len); +static void where_to_send_deallocate(POOL_QUERY_CONTEXT * query_context, Node *node); +static char *remove_read_write(int len, const char *contents, int *rewritten_len); /* * Create and initialize per query session context */ -POOL_QUERY_CONTEXT *pool_init_query_context(void) +POOL_QUERY_CONTEXT * +pool_init_query_context(void) { MemoryContext memory_context = AllocSetContextCreate(QueryContext, - "QueryContextMemoryContext", - ALLOCSET_SMALL_MINSIZE, - ALLOCSET_SMALL_INITSIZE, - ALLOCSET_SMALL_MAXSIZE); + "QueryContextMemoryContext", + ALLOCSET_SMALL_MINSIZE, + ALLOCSET_SMALL_INITSIZE, + ALLOCSET_SMALL_MAXSIZE); MemoryContext oldcontext = MemoryContextSwitchTo(memory_context); POOL_QUERY_CONTEXT *qc; + qc = palloc0(sizeof(*qc)); qc->memory_context = memory_context; MemoryContextSwitchTo(oldcontext); @@ -77,7 +80,8 @@ POOL_QUERY_CONTEXT *pool_init_query_context(void) /* * Destroy query context */ -void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context) +void +pool_query_context_destroy(POOL_QUERY_CONTEXT * query_context) { POOL_SESSION_CONTEXT *session_context; @@ -93,7 +97,7 @@ void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context) if (!pool_is_command_success() && query_context->pg_terminate_backend_conn) { ereport(DEBUG1, - (errmsg("clearing the connection flag for pg_terminate_backend"))); + (errmsg("clearing the connection flag for pg_terminate_backend"))); pool_unset_connection_will_be_terminated(query_context->pg_terminate_backend_conn); } query_context->pg_terminate_backend_conn = NULL; @@ -107,7 +111,8 @@ void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context) /* * Perform shallow copy of given query context. Used in parse_before_bind. */ -POOL_QUERY_CONTEXT *pool_query_context_shallow_copy(POOL_QUERY_CONTEXT *query_context) +POOL_QUERY_CONTEXT * +pool_query_context_shallow_copy(POOL_QUERY_CONTEXT * query_context) { POOL_QUERY_CONTEXT *qc; MemoryContext memory_context; @@ -122,13 +127,15 @@ POOL_QUERY_CONTEXT *pool_query_context_shallow_copy(POOL_QUERY_CONTEXT *query_co /* * Start query */ -void pool_start_query(POOL_QUERY_CONTEXT *query_context, char *query, int len, Node *node) +void +pool_start_query(POOL_QUERY_CONTEXT * query_context, char *query, int len, Node *node) { POOL_SESSION_CONTEXT *session_context; if (query_context) { MemoryContext old_context; + session_context = pool_get_session_context(false); old_context = MemoryContextSwitchTo(query_context->memory_context); query_context->original_length = len; @@ -151,14 +158,15 @@ void pool_start_query(POOL_QUERY_CONTEXT *query_context, char *query, int len, N /* * Specify DB node to send query */ -void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) +void +pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) { CHECK_QUERY_CONTEXT_IS_VALID; if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) ereport(ERROR, - (errmsg("setting db node for query to be sent, invalid node id:%d",node_id), - errdetail("backend node id: %d out of range, node id can be between 0 and %d",node_id,MAX_NUM_BACKENDS))); + (errmsg("setting db node for query to be sent, invalid node id:%d", node_id), + errdetail("backend node id: %d out of range, node id can be between 0 and %d", node_id, MAX_NUM_BACKENDS))); query_context->where_to_send[node_id] = true; @@ -168,14 +176,15 @@ void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) /* * Unspecify DB node to send query */ -void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) +void +pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) { CHECK_QUERY_CONTEXT_IS_VALID; if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) ereport(ERROR, - (errmsg("un setting db node for query to be sent, invalid node id:%d",node_id), - errdetail("backend node id: %d out of range, node id can be between 0 and %d",node_id,MAX_NUM_BACKENDS))); + (errmsg("un setting db node for query to be sent, invalid node id:%d", node_id), + errdetail("backend node id: %d out of range, node id can be between 0 and %d", node_id, MAX_NUM_BACKENDS))); query_context->where_to_send[node_id] = false; @@ -185,7 +194,8 @@ void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) /* * Clear DB node map */ -void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) +void +pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) { CHECK_QUERY_CONTEXT_IS_VALID; @@ -196,24 +206,24 @@ void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) /* * Set all DB node map entry */ -void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) +void +pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) { - int i; + int i; POOL_SESSION_CONTEXT *sc; sc = pool_get_session_context(false); CHECK_QUERY_CONTEXT_IS_VALID; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (private_backend_status[i] == CON_UP || (private_backend_status[i] == CON_CONNECT_WAIT)) { /* - * In streaming replication mode, if the node is not - * primary node nor load balance node, there's no point to - * send query. + * In streaming replication mode, if the node is not primary node + * nor load balance node, there's no point to send query. */ if (SL_MODE && i != PRIMARY_NODE_ID && i != sc->load_balance_node_id) @@ -229,14 +239,15 @@ void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) /* * Return true if multiple nodes are targets */ -bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) +bool +pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT * query_context) { - int i; - int cnt = 0; + int i; + int cnt = 0; CHECK_QUERY_CONTEXT_IS_VALID; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (((BACKEND_INFO(i)).backend_status == CON_UP || BACKEND_INFO((i)).backend_status == CON_CONNECT_WAIT) && @@ -255,14 +266,15 @@ bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context) /* * Return if the DB node is needed to send query */ -bool pool_is_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) +bool +pool_is_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id) { CHECK_QUERY_CONTEXT_IS_VALID; if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) ereport(ERROR, - (errmsg("checking if db node is needed to be sent, invalid node id:%d",node_id), - errdetail("backend node id: %d out of range, node id can be between 0 and %d",node_id,MAX_NUM_BACKENDS))); + (errmsg("checking if db node is needed to be sent, invalid node id:%d", node_id), + errdetail("backend node id: %d out of range, node id can be between 0 and %d", node_id, MAX_NUM_BACKENDS))); return query_context->where_to_send[node_id]; } @@ -271,7 +283,8 @@ bool pool_is_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id) * Returns true if the DB node is needed to send query. * Intended to be called from VALID_BACKEND */ -bool pool_is_node_to_be_sent_in_current_query(int node_id) +bool +pool_is_node_to_be_sent_in_current_query(int node_id) { POOL_SESSION_CONTEXT *sc; @@ -292,7 +305,8 @@ bool pool_is_node_to_be_sent_in_current_query(int node_id) /* * Returns virtual master DB node id, */ -int pool_virtual_master_db_node_id(void) +int +pool_virtual_master_db_node_id(void) { POOL_SESSION_CONTEXT *sc; @@ -304,24 +318,24 @@ int pool_virtual_master_db_node_id(void) if (sc->in_progress && sc->query_context) { - int node_id = sc->query_context->virtual_master_node_id; + int node_id = sc->query_context->virtual_master_node_id; if (SL_MODE) { - /* - * Make sure that virtual_master_node_id is either primary node - * id or load balance node id. If not, it is likely that - * virtual_master_node_id is not set up yet. Let's use the - * primary node id. except for the special case where we need - * to send the query to the node which is not primary nor the - * load balance node. Currently there is only one special such - * case that is handling of pg_terminate_backend() function, which - * may refer to the backend connection that is neither hosted by - * the primary or load balance node for current child process, but - * the query must be forwarded to that node. Since only that backend - * node can handle that pg_terminate_backend query - * - */ + /* + * Make sure that virtual_master_node_id is either primary node id + * or load balance node id. If not, it is likely that + * virtual_master_node_id is not set up yet. Let's use the primary + * node id. except for the special case where we need to send the + * query to the node which is not primary nor the load balance + * node. Currently there is only one special such case that is + * handling of pg_terminate_backend() function, which may refer to + * the backend connection that is neither hosted by the primary or + * load balance node for current child process, but the query must + * be forwarded to that node. Since only that backend node can + * handle that pg_terminate_backend query + * + */ ereport(DEBUG5, (errmsg("pool_virtual_master_db_node_id: virtual_master_node_id:%d load_balance_node_id:%d PRIMARY_NODE_ID:%d", @@ -330,8 +344,8 @@ int pool_virtual_master_db_node_id(void) if (node_id != sc->load_balance_node_id && node_id != PRIMARY_NODE_ID) { /* - * Only return the primary node id if we are not processing the - * pg_terminate_backend query + * Only return the primary node id if we are not processing + * the pg_terminate_backend query */ if (sc->query_context->pg_terminate_backend_conn == NULL) node_id = PRIMARY_NODE_ID; @@ -342,9 +356,9 @@ int pool_virtual_master_db_node_id(void) } /* - * No query context exists. If in master/slave mode, returns - * primary node if exists. Otherwise returns my_master_node_id, - * which represents the last REAL_MASTER_NODE_ID. + * No query context exists. If in master/slave mode, returns primary node + * if exists. Otherwise returns my_master_node_id, which represents the + * last REAL_MASTER_NODE_ID. */ if (MASTER_SLAVE) { @@ -356,16 +370,18 @@ int pool_virtual_master_db_node_id(void) /* * The function sets the destination for the current query to the specific backend node */ -void pool_force_query_node_to_backend(POOL_QUERY_CONTEXT *query_context, int backend_id) +void +pool_force_query_node_to_backend(POOL_QUERY_CONTEXT * query_context, int backend_id) { - int i; + int i; + CHECK_QUERY_CONTEXT_IS_VALID; ereport(DEBUG1, - (errmsg("forcing query destination node to backend node:%d",backend_id))); + (errmsg("forcing query destination node to backend node:%d", backend_id))); - pool_set_node_to_be_sent(query_context,backend_id); - for (i=0;i<NUM_BACKENDS;i++) + pool_set_node_to_be_sent(query_context, backend_id); + for (i = 0; i < NUM_BACKENDS; i++) { if (query_context->where_to_send[i]) { @@ -378,11 +394,12 @@ void pool_force_query_node_to_backend(POOL_QUERY_CONTEXT *query_context, int bac /* * Decide where to send queries(thus expecting response) */ -void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *node) +void +pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node) { POOL_SESSION_CONTEXT *session_context; POOL_CONNECTION_POOL *backend; - int i; + int i; CHECK_QUERY_CONTEXT_IS_VALID; @@ -392,11 +409,11 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no /* * Zap out DB node map */ - pool_clear_node_to_be_sent(query_context); + pool_clear_node_to_be_sent(query_context); /* - * When query match the query patterns in black_query_pattern_list, - * we send only to master node. + * When query match the query patterns in black_query_pattern_list, we + * send only to master node. */ if (MASTER_SLAVE && pattern_compare(query, BLACKLIST, "black_query_pattern_list") == 1) { @@ -411,7 +428,7 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no { pool_set_node_to_be_sent(query_context, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (query_context->where_to_send[i]) { @@ -432,18 +449,16 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no else if (MASTER_SLAVE && query_context->is_multi_statement) { /* - * If we are in master/slave mode and we have multi statement - * query, we should send it to primary server only. Otherwise - * it is possible to send a write query to standby servers - * because we only use the first element of the multi - * statement query and don't care about the rest. Typical - * situation where we are bugged by this is, "BEGIN;DELETE - * FROM table;END". Note that from pgpool-II 3.1.0 - * transactional statements such as "BEGIN" is unconditionally - * sent to all nodes(see send_to_where() for more details). - * Someday we might be able to understand all part of multi - * statement queries, but until that day we need this band - * aid. + * If we are in master/slave mode and we have multi statement query, + * we should send it to primary server only. Otherwise it is possible + * to send a write query to standby servers because we only use the + * first element of the multi statement query and don't care about the + * rest. Typical situation where we are bugged by this is, + * "BEGIN;DELETE FROM table;END". Note that from pgpool-II 3.1.0 + * transactional statements such as "BEGIN" is unconditionally sent to + * all nodes(see send_to_where() for more details). Someday we might + * be able to understand all part of multi statement queries, but + * until that day we need this band aid. */ if (query_context->is_multi_statement) { @@ -452,12 +467,12 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no } else if (MASTER_SLAVE) { - POOL_DEST dest; + POOL_DEST dest; dest = send_to_where(node, query); ereport(DEBUG1, - (errmsg("decide where to send the query"), + (errmsg("decide where to send the query"), errdetail("destination = %d for query= \"%s\"", dest, query))); /* Should be sent to primary only? */ @@ -486,10 +501,10 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no MAJOR(backend) == PROTO_MAJOR_V3) { /* - * If (we are outside of an explicit transaction) OR - * (the transaction has not issued a write query yet, AND - * transaction isolation level is not SERIALIZABLE) - * we might be able to load balance. + * If (we are outside of an explicit transaction) OR (the + * transaction has not issued a write query yet, AND + * transaction isolation level is not SERIALIZABLE) we might + * be able to load balance. */ ereport(DEBUG1, @@ -512,7 +527,8 @@ 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 replication delay is too much, we prefer to send to + * the primary. */ if (STREAM && pool_config->delay_threshold && @@ -526,8 +542,8 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no } /* - * If a writing function call is used, - * we prefer to send to the primary. + * If a writing function call is used, we prefer to send + * to the primary. */ else if (pool_has_function_call(node)) { @@ -539,16 +555,14 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no } /* - * If system catalog is used in the SELECT, we - * prefer to send to the primary. Example: SELECT - * * FROM pg_class WHERE relname = 't1'; Because - * 't1' is a constant, it's hard to recognize as - * table name. Most use case such query is - * against system catalog, and the table name can - * be a temporary table, it's best to query - * against primary system catalog. - * Please note that this test must be done *before* - * test using pool_has_temp_table. + * If system catalog is used in the SELECT, we prefer to + * send to the primary. Example: SELECT * FROM pg_class + * WHERE relname = 't1'; Because 't1' is a constant, it's + * hard to recognize as table name. Most use case such + * query is against system catalog, and the table name can + * be a temporary table, it's best to query against + * primary system catalog. Please note that this test must + * be done *before* test using pool_has_temp_table. */ else if (pool_has_system_catalog(node)) { @@ -560,8 +574,8 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no } /* - * If temporary table is used in the SELECT, - * we prefer to send to the primary. + * If temporary table is used in the SELECT, we prefer to + * send to the primary. */ else if (pool_config->check_temp_table && pool_has_temp_table(node)) { @@ -573,8 +587,8 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no } /* - * If unlogged table is used in the SELECT, - * we prefer to send to the primary. + * If unlogged table is used in the SELECT, we prefer to + * send to the primary. */ else if (pool_config->check_unlogged_table && pool_has_unlogged_table(node)) { @@ -618,11 +632,12 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no { pool_setall_node_to_be_sent(query_context); } + /* - * If (we are outside of an explicit transaction) OR - * (the transaction has not issued a write query yet, AND - * transaction isolation level is not SERIALIZABLE) - * we might be able to load balance. + * If (we are outside of an explicit transaction) OR (the + * transaction has not issued a write query yet, AND transaction + * isolation level is not SERIALIZABLE) we might be able to load + * balance. */ else if (TSTATE(backend, MASTER_NODE_ID) == 'I' || (!pool_is_writing_transaction() && @@ -668,9 +683,9 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no { POOL_SENT_MESSAGE *msg; - msg = pool_get_sent_message('Q', ((ExecuteStmt *)node)->name, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('Q', ((ExecuteStmt *) node)->name, POOL_SENT_MESSAGE_CREATED); if (!msg) - msg = pool_get_sent_message('P', ((ExecuteStmt *)node)->name, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('P', ((ExecuteStmt *) node)->name, POOL_SENT_MESSAGE_CREATED); if (msg) pool_copy_prep_where(msg->query_context->where_to_send, query_context->where_to_send); @@ -684,7 +699,7 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no where_to_send_deallocate(query_context, node); } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (query_context->where_to_send[i]) { @@ -703,17 +718,18 @@ void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *no * 0: send to all nodes * >0: send to this node_id */ -POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, - int send_type, int node_id) +POOL_STATUS +pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, + int send_type, int node_id) { POOL_SESSION_CONTEXT *session_context; POOL_CONNECTION *frontend; POOL_CONNECTION_POOL *backend; - bool is_commit; - bool is_begin_read_write; - int i; - int len; - char *string; + bool is_commit; + bool is_begin_read_write; + int i; + int len; + char *string; session_context = pool_get_session_context(false); frontend = session_context->frontend; @@ -724,9 +740,8 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, string = NULL; /* - * If the query is BEGIN READ WRITE or - * BEGIN ... SERIALIZABLE in master/slave mode, - * we send BEGIN to slaves/standbys instead. + * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE in + * master/slave mode, we send BEGIN to slaves/standbys instead. * original_query which is BEGIN READ WRITE is sent to primary. * rewritten_query which is BEGIN is sent to standbys. */ @@ -749,7 +764,7 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, } /* Send query */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -769,9 +784,8 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, } /* - * If in reset context, we send COMMIT/ABORT to nodes those - * are not in I(idle) state. This will ensure that - * transactions are closed. + * If in reset context, we send COMMIT/ABORT to nodes those are not in + * I(idle) state. This will ensure that transactions are closed. */ if (is_commit && session_context->reset_context && TSTATE(backend, i) == 'I') { @@ -799,7 +813,7 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, } /* Wait for response */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -809,6 +823,7 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, continue; #ifdef NOT_USED + /* * If in master/slave mode, we do not send COMMIT/ABORT to * slaves/standbys if it's in I(idle) state. @@ -821,24 +836,22 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, if (is_begin_read_write) { - if(REAL_PRIMARY_NODE_ID == i) + if (REAL_PRIMARY_NODE_ID == i) string = query_context->original_query; else string = query_context->rewritten_query; } - wait_for_query_response_with_trans_cleanup(frontend, - CONNECTION(backend, i), - MAJOR(backend), - MASTER_CONNECTION(backend)->pid, - MASTER_CONNECTION(backend)->key); + wait_for_query_response_with_trans_cleanup(frontend, + CONNECTION(backend, i), + MAJOR(backend), + MASTER_CONNECTION(backend)->pid, + MASTER_CONNECTION(backend)->key); /* - * Check if some error detected. If so, emit - * log. This is useful when invalid encoding error - * occurs. In this case, PostgreSQL does not report - * what statement caused that error and make users - * confused. + * Check if some error detected. If so, emit log. This is useful when + * invalid encoding error occurs. In this case, PostgreSQL does not + * report what statement caused that error and make users confused. */ per_node_error_log(backend, i, string, "pool_send_and_wait: Error or notice message from backend: ", true); } @@ -853,20 +866,21 @@ POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, * 0: send to all nodes * >0: send to this node_id */ -POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, - char *kind, int len, char *contents, - int send_type, int node_id, bool nowait) +POOL_STATUS +pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, + char *kind, int len, char *contents, + int send_type, int node_id, bool nowait) { POOL_SESSION_CONTEXT *session_context; POOL_CONNECTION *frontend; POOL_CONNECTION_POOL *backend; - bool is_commit; - bool is_begin_read_write; - int i; - int str_len; - int rewritten_len; - char *str; - char *rewritten_begin; + bool is_commit; + bool is_begin_read_write; + int i; + int str_len; + int rewritten_len; + char *str; + char *rewritten_begin; session_context = pool_get_session_context(false); frontend = session_context->frontend; @@ -879,9 +893,8 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, rewritten_begin = NULL; /* - * If the query is BEGIN READ WRITE or - * BEGIN ... SERIALIZABLE in master/slave mode, - * we send BEGIN to slaves/standbys instead. + * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE in + * master/slave mode, we send BEGIN to slaves/standbys instead. * original_query which is BEGIN READ WRITE is sent to primary. * rewritten_query which is BEGIN is sent to standbys. */ @@ -900,7 +913,7 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, } /* Send query */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -910,9 +923,8 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, continue; /* - * If in reset context, we send COMMIT/ABORT to nodes those - * are not in I(idle) state. This will ensure that - * transactions are closed. + * If in reset context, we send COMMIT/ABORT to nodes those are not in + * I(idle) state. This will ensure that transactions are closed. */ if (is_commit && session_context->reset_context && TSTATE(backend, i) == 'I') { @@ -936,8 +948,8 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, if (pool_config->log_per_node_statement) { - char msgbuf[QUERY_STRING_BUFFER_LEN]; - char *stmt; + char msgbuf[QUERY_STRING_BUFFER_LEN]; + char *stmt; if (*kind == 'P' || *kind == 'E') { @@ -984,12 +996,12 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, if ((*kind == 'P' || *kind == 'E' || *kind == 'C') && STREAM) { /* - * Send flush message to backend to make sure that we get any response - * from backend in Streaming replication mode. + * Send flush message to backend to make sure that we get any + * response from backend in Streaming replication mode. */ POOL_CONNECTION *cp = CONNECTION(backend, i); - int len; + int len; pool_write(cp, "H", 1); len = htonl(sizeof(len)); @@ -1011,7 +1023,7 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, if (!nowait) { /* Wait for response */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -1044,18 +1056,17 @@ POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, MASTER_CONNECTION(backend)->key); /* - * Check if some error detected. If so, emit - * log. This is useful when invalid encoding error - * occurs. In this case, PostgreSQL does not report - * what statement caused that error and make users + * Check if some error detected. If so, emit log. This is useful + * when invalid encoding error occurs. In this case, PostgreSQL + * does not report what statement caused that error and make users * confused. */ per_node_error_log(backend, i, str, "pool_send_and_wait: Error or notice message from backend: ", true); } } - if(rewritten_begin) - pfree(rewritten_begin); + if (rewritten_begin) + pfree(rewritten_begin); return POOL_CONTINUE; } @@ -1068,18 +1079,17 @@ static POOL_DEST send_to_where(Node *node, char *query) { /* From storage/lock.h */ #define NoLock 0 -#define AccessShareLock 1 /* SELECT */ -#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */ -#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */ -#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE - * INDEX CONCURRENTLY */ -#define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */ -#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW - * SHARE */ -#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR - * UPDATE */ -#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM - * FULL, and unqualified LOCK TABLE */ +#define AccessShareLock 1 /* SELECT */ +#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */ +#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */ +#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL),ANALYZE, CREATE INDEX + * CONCURRENTLY */ +#define ShareLock 5 /* CREATE INDEX (WITHOUT CONCURRENTLY) */ +#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW + * SHARE */ +#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR UPDATE */ +#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM FULL, + * and unqualified LOCK TABLE */ /* From 9.5 include/nodes/node.h ("TAGS FOR STATEMENT NODES" part) */ static NodeTag nodemap[] = { @@ -1100,23 +1110,23 @@ static POOL_DEST send_to_where(Node *node, char *query) T_ClosePortalStmt, T_ClusterStmt, T_CopyStmt, - T_CreateStmt, /* CREATE TABLE */ - T_DefineStmt, /* CREATE AGGREGATE, OPERATOR, TYPE */ - T_DropStmt, /* DROP TABLE etc. */ + T_CreateStmt, /* CREATE TABLE */ + T_DefineStmt, /* CREATE AGGREGATE, OPERATOR, TYPE */ + T_DropStmt, /* DROP TABLE etc. */ T_TruncateStmt, T_CommentStmt, T_FetchStmt, - T_IndexStmt, /* CREATE INDEX */ + T_IndexStmt, /* CREATE INDEX */ T_CreateFunctionStmt, T_AlterFunctionStmt, T_DoStmt, - T_RenameStmt, /* ALTER AGGREGATE etc. */ - T_RuleStmt, /* CREATE RULE */ + T_RenameStmt, /* ALTER AGGREGATE etc. */ + T_RuleStmt, /* CREATE RULE */ T_NotifyStmt, T_ListenStmt, T_UnlistenStmt, T_TransactionStmt, - T_ViewStmt, /* CREATE VIEW */ + T_ViewStmt, /* CREATE VIEW */ T_LoadStmt, T_CreateDomainStmt, T_CreatedbStmt, @@ -1195,12 +1205,11 @@ static POOL_DEST send_to_where(Node *node, char *query) T_AlterCollationStmt, }; - if (bsearch(&nodeTag(node), nodemap, sizeof(nodemap)/sizeof(nodemap[0]), + if (bsearch(&nodeTag(node), nodemap, sizeof(nodemap) / sizeof(nodemap[0]), sizeof(NodeTag), compare) != NULL) { /* - * SELECT INTO - * SELECT FOR SHARE or UPDATE + * SELECT INTO SELECT FOR SHARE or UPDATE */ if (IsA(node, SelectStmt)) { @@ -1209,13 +1218,15 @@ static POOL_DEST send_to_where(Node *node, char *query) return POOL_PRIMARY; /* non-SELECT query in WITH clause ? */ - if (((SelectStmt *)node)->withClause) + if (((SelectStmt *) node)->withClause) { - List *ctes = ((SelectStmt *)node)->withClause->ctes; + List *ctes = ((SelectStmt *) node)->withClause->ctes; ListCell *cte_item; + foreach(cte_item, ctes) { - CommonTableExpr *cte = (CommonTableExpr *)lfirst(cte_item); + CommonTableExpr *cte = (CommonTableExpr *) lfirst(cte_item); + if (!IsA(cte->ctequery, SelectStmt)) return POOL_PRIMARY; } @@ -1229,14 +1240,14 @@ static POOL_DEST send_to_where(Node *node, char *query) */ else if (IsA(node, CopyStmt)) { - if (((CopyStmt *)node)->is_from) + if (((CopyStmt *) node)->is_from) return POOL_PRIMARY; else { - if (((CopyStmt *)node)->query == NULL) + if (((CopyStmt *) node)->query == NULL) return POOL_EITHER; else - return (IsA(((CopyStmt *)node)->query, SelectStmt))?POOL_EITHER:POOL_PRIMARY; + return (IsA(((CopyStmt *) node)->query, SelectStmt)) ? POOL_EITHER : POOL_PRIMARY; } } @@ -1245,7 +1256,7 @@ static POOL_DEST send_to_where(Node *node, char *query) */ else if (IsA(node, LockStmt)) { - return (((LockStmt *)node)->mode >= RowExclusiveLock)?POOL_PRIMARY:POOL_BOTH; + return (((LockStmt *) node)->mode >= RowExclusiveLock) ? POOL_PRIMARY : POOL_BOTH; } /* @@ -1258,18 +1269,24 @@ static POOL_DEST send_to_where(Node *node, char *query) */ if (is_start_transaction_query(node)) { - /* But actually, we send BEGIN to standby if it's - BEGIN READ WRITE or START TRANSACTION READ WRITE */ - if (is_read_write((TransactionStmt *)node)) + /* + * But actually, we send BEGIN to standby if it's BEGIN READ + * WRITE or START TRANSACTION READ WRITE + */ + if (is_read_write((TransactionStmt *) node)) return POOL_BOTH; - /* Other TRANSACTION start commands are sent to both primary - and standby */ + + /* + * Other TRANSACTION start commands are sent to both primary + * and standby + */ else return POOL_BOTH; } /* SAVEPOINT related commands are sent to both primary and standby */ else if (is_savepoint_query(node)) return POOL_BOTH; + /* * 2PC commands */ @@ -1286,18 +1303,19 @@ static POOL_DEST send_to_where(Node *node, char *query) else if (IsA(node, VariableSetStmt)) { ListCell *list_item; - bool ret = POOL_BOTH; + bool ret = POOL_BOTH; /* * SET transaction_read_only TO off */ - if (((VariableSetStmt *)node)->kind == VAR_SET_VALUE && - !strcmp(((VariableSetStmt *)node)->name, "transaction_read_only")) + if (((VariableSetStmt *) node)->kind == VAR_SET_VALUE && + !strcmp(((VariableSetStmt *) node)->name, "transaction_read_only")) { - List *options = ((VariableSetStmt *)node)->args; + List *options = ((VariableSetStmt *) node)->args; + foreach(list_item, options) { - A_Const *v = (A_Const *)lfirst(list_item); + A_Const *v = (A_Const *) lfirst(list_item); switch (v->val.type) { @@ -1317,10 +1335,11 @@ static POOL_DEST send_to_where(Node *node, char *query) return ret; } - /* SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or - * SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE or - * SET transaction_isolation TO 'serializable' - * SET default_transaction_isolation TO 'serializable' + /* + * SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET SESSION + * CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE or + * SET transaction_isolation TO 'serializable' SET + * default_transaction_isolation TO 'serializable' */ else if (is_set_transaction_serializable(node)) { @@ -1328,23 +1347,24 @@ static POOL_DEST send_to_where(Node *node, char *query) } /* - * Check "SET TRANSACTION READ WRITE" "SET SESSION - * CHARACTERISTICS AS TRANSACTION READ WRITE" + * Check "SET TRANSACTION READ WRITE" "SET SESSION CHARACTERISTICS + * AS TRANSACTION READ WRITE" */ - else if (((VariableSetStmt *)node)->kind == VAR_SET_MULTI && - (!strcmp(((VariableSetStmt *)node)->name, "TRANSACTION") || - !strcmp(((VariableSetStmt *)node)->name, "SESSION CHARACTERISTICS"))) + else if (((VariableSetStmt *) node)->kind == VAR_SET_MULTI && + (!strcmp(((VariableSetStmt *) node)->name, "TRANSACTION") || + !strcmp(((VariableSetStmt *) node)->name, "SESSION CHARACTERISTICS"))) { - List *options = ((VariableSetStmt *)node)->args; + List *options = ((VariableSetStmt *) node)->args; + foreach(list_item, options) { - DefElem *opt = (DefElem *) lfirst(list_item); + DefElem *opt = (DefElem *) lfirst(list_item); if (!strcmp("transaction_read_only", opt->defname)) { - bool read_only; + bool read_only; - read_only = ((A_Const *)opt->arg)->val.val.ival; + read_only = ((A_Const *) opt->arg)->val.val.ival; if (!read_only) return POOL_PRIMARY; } @@ -1354,8 +1374,7 @@ static POOL_DEST send_to_where(Node *node, char *query) else { /* - * All other SET command sent to both primary and - * standby + * All other SET command sent to both primary and standby */ return POOL_BOTH; } @@ -1374,12 +1393,12 @@ static POOL_DEST send_to_where(Node *node, char *query) */ else if (IsA(node, PrepareStmt)) { - PrepareStmt *prepare_statement = (PrepareStmt *)node; + PrepareStmt *prepare_statement = (PrepareStmt *) node; - char *string = nodeToString(prepare_statement->query); + char *string = nodeToString(prepare_statement->query); /* Note that this is a recursive call */ - return send_to_where((Node *)(prepare_statement->query), string); + return send_to_where((Node *) (prepare_statement->query), string); } /* @@ -1387,8 +1406,9 @@ static POOL_DEST send_to_where(Node *node, char *query) */ else if (IsA(node, ExecuteStmt)) { - /* This is temporary decision. where_to_send will inherit - * same destination AS PREPARE. + /* + * This is temporary decision. where_to_send will inherit same + * destination AS PREPARE. */ return POOL_PRIMARY; } @@ -1398,11 +1418,13 @@ static POOL_DEST send_to_where(Node *node, char *query) */ else if (IsA(node, DeallocateStmt)) { - /* This is temporary decision. where_to_send will inherit - * same destination AS PREPARE. + /* + * This is temporary decision. where_to_send will inherit same + * destination AS PREPARE. */ return POOL_PRIMARY; } + /* * SHOW */ @@ -1424,9 +1446,10 @@ static POOL_DEST send_to_where(Node *node, char *query) } static -void where_to_send_deallocate(POOL_QUERY_CONTEXT *query_context, Node *node) +void +where_to_send_deallocate(POOL_QUERY_CONTEXT * query_context, Node *node) { - DeallocateStmt *d = (DeallocateStmt *)node; + DeallocateStmt *d = (DeallocateStmt *) node; POOL_SENT_MESSAGE *msg; /* DEALLOCATE ALL? */ @@ -1455,7 +1478,8 @@ void where_to_send_deallocate(POOL_QUERY_CONTEXT *query_context, Node *node) * Returns parse tree for current query. * Precondition: the query is in progress state. */ -Node *pool_get_parse_tree(void) +Node * +pool_get_parse_tree(void) { POOL_SESSION_CONTEXT *sc; @@ -1474,7 +1498,8 @@ Node *pool_get_parse_tree(void) * Returns raw query string for current query. * Precondition: the query is in progress state. */ -char *pool_get_query_string(void) +char * +pool_get_query_string(void) { POOL_SESSION_CONTEXT *sc; @@ -1497,21 +1522,23 @@ char *pool_get_query_string(void) * SET transaction_isolation TO 'serializable' * SET default_transaction_isolation TO 'serializable' */ -bool is_set_transaction_serializable(Node *node) +bool +is_set_transaction_serializable(Node *node) { ListCell *list_item; if (!IsA(node, VariableSetStmt)) return false; - if (((VariableSetStmt *)node)->kind == VAR_SET_VALUE && - (!strcmp(((VariableSetStmt *)node)->name, "transaction_isolation") || - !strcmp(((VariableSetStmt *)node)->name, "default_transaction_isolation"))) + if (((VariableSetStmt *) node)->kind == VAR_SET_VALUE && + (!strcmp(((VariableSetStmt *) node)->name, "transaction_isolation") || + !strcmp(((VariableSetStmt *) node)->name, "default_transaction_isolation"))) { - List *options = ((VariableSetStmt *)node)->args; + List *options = ((VariableSetStmt *) node)->args; + foreach(list_item, options) { - A_Const *v = (A_Const *)lfirst(list_item); + A_Const *v = (A_Const *) lfirst(list_item); switch (v->val.type) { @@ -1526,18 +1553,20 @@ bool is_set_transaction_serializable(Node *node) return false; } - else if (((VariableSetStmt *)node)->kind == VAR_SET_MULTI && - (!strcmp(((VariableSetStmt *)node)->name, "TRANSACTION") || - !strcmp(((VariableSetStmt *)node)->name, "SESSION CHARACTERISTICS"))) + else if (((VariableSetStmt *) node)->kind == VAR_SET_MULTI && + (!strcmp(((VariableSetStmt *) node)->name, "TRANSACTION") || + !strcmp(((VariableSetStmt *) node)->name, "SESSION CHARACTERISTICS"))) { - List *options = ((VariableSetStmt *)node)->args; + List *options = ((VariableSetStmt *) node)->args; + foreach(list_item, options) { - DefElem *opt = (DefElem *) lfirst(list_item); + DefElem *opt = (DefElem *) lfirst(list_item); + if (!strcmp("transaction_isolation", opt->defname) || !strcmp("default_transaction_isolation", opt->defname)) { - A_Const *v = (A_Const *)opt->arg; + A_Const *v = (A_Const *) opt->arg; if (!strcasecmp(v->val.val.str, "serializable")) return true; @@ -1551,40 +1580,44 @@ bool is_set_transaction_serializable(Node *node) * Returns true if SQL is transaction starting command (START * TRANSACTION or BEGIN) */ -bool is_start_transaction_query(Node *node) +bool +is_start_transaction_query(Node *node) { TransactionStmt *stmt; if (node == NULL || !IsA(node, TransactionStmt)) return false; - stmt = (TransactionStmt *)node; + stmt = (TransactionStmt *) node; return stmt->kind == TRANS_STMT_START || stmt->kind == TRANS_STMT_BEGIN; } /* * Return true if start transaction query with "READ WRITE" option. */ -bool is_read_write(TransactionStmt *node) +bool +is_read_write(TransactionStmt *node) { ListCell *list_item; - List *options = node->options; + List *options = node->options; + foreach(list_item, options) { - DefElem *opt = (DefElem *) lfirst(list_item); + DefElem *opt = (DefElem *) lfirst(list_item); if (!strcmp("transaction_read_only", opt->defname)) { - bool read_only; + bool read_only; - read_only = ((A_Const *)opt->arg)->val.val.ival; + read_only = ((A_Const *) opt->arg)->val.val.ival; if (read_only) return false; /* TRANSACTION READ ONLY */ else + /* - * TRANSACTION READ WRITE specified. This sounds a little bit strange, - * but actually the parse code works in the way. + * TRANSACTION READ WRITE specified. This sounds a little bit + * strange, but actually the parse code works in the way. */ return true; } @@ -1599,20 +1632,22 @@ bool is_read_write(TransactionStmt *node) /* * Return true if start transaction query with "SERIALIZABLE" option. */ -bool is_serializable(TransactionStmt *node) +bool +is_serializable(TransactionStmt *node) { ListCell *list_item; - List *options = node->options; + List *options = node->options; + foreach(list_item, options) { - DefElem *opt = (DefElem *) lfirst(list_item); + DefElem *opt = (DefElem *) lfirst(list_item); if (!strcmp("transaction_isolation", opt->defname) && IsA(opt->arg, A_Const) && - ((A_Const *)opt->arg)->val.type == T_String && - !strcmp("serializable", ((A_Const *)opt->arg)->val.val.str)) - return true; + ((A_Const *) opt->arg)->val.type == T_String && + !strcmp("serializable", ((A_Const *) opt->arg)->val.val.str)) + return true; } return false; } @@ -1624,22 +1659,24 @@ bool is_serializable(TransactionStmt *node) * original_query which is BEGIN READ WRITE is sent to primary. * rewritten_query which is BEGIN is sent to standbys. */ -bool pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT *query_context) +bool +pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT * query_context) { return (MASTER_SLAVE && is_start_transaction_query(query_context->parse_tree) && - (is_read_write((TransactionStmt *)query_context->parse_tree) || - is_serializable((TransactionStmt *)query_context->parse_tree))); + (is_read_write((TransactionStmt *) query_context->parse_tree) || + is_serializable((TransactionStmt *) query_context->parse_tree))); } /* * Return true if the query is SAVEPOINT related query. */ -bool is_savepoint_query(Node *node) +bool +is_savepoint_query(Node *node) { - if (((TransactionStmt *)node)->kind == TRANS_STMT_SAVEPOINT || - ((TransactionStmt *)node)->kind == TRANS_STMT_ROLLBACK_TO || - ((TransactionStmt *)node)->kind == TRANS_STMT_RELEASE) + if (((TransactionStmt *) node)->kind == TRANS_STMT_SAVEPOINT || + ((TransactionStmt *) node)->kind == TRANS_STMT_ROLLBACK_TO || + ((TransactionStmt *) node)->kind == TRANS_STMT_RELEASE) return true; return false; @@ -1648,11 +1685,12 @@ bool is_savepoint_query(Node *node) /* * Return true if the query is 2PC transaction query. */ -bool is_2pc_transaction_query(Node *node) +bool +is_2pc_transaction_query(Node *node) { - if (((TransactionStmt *)node)->kind == TRANS_STMT_PREPARE || - ((TransactionStmt *)node)->kind == TRANS_STMT_COMMIT_PREPARED || - ((TransactionStmt *)node)->kind == TRANS_STMT_ROLLBACK_PREPARED) + if (((TransactionStmt *) node)->kind == TRANS_STMT_PREPARE || + ((TransactionStmt *) node)->kind == TRANS_STMT_COMMIT_PREPARED || + ((TransactionStmt *) node)->kind == TRANS_STMT_ROLLBACK_PREPARED) return true; return false; @@ -1661,9 +1699,10 @@ bool is_2pc_transaction_query(Node *node) /* * Set query state, if a current state is before it than the specified state. */ -void pool_set_query_state(POOL_QUERY_CONTEXT *query_context, POOL_QUERY_STATE state) +void +pool_set_query_state(POOL_QUERY_CONTEXT * query_context, POOL_QUERY_STATE state) { - int i; + int i; CHECK_QUERY_CONTEXT_IS_VALID; @@ -1680,11 +1719,13 @@ void pool_set_query_state(POOL_QUERY_CONTEXT *query_context, POOL_QUERY_STATE st * transition order. * The State transition order is defined as: UNPARSED < PARSE_COMPLETE < BIND_COMPLETE < EXECUTE_COMPLETE */ -int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2) +int +statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2) { - int ret; + int ret; - switch (s2) { + switch (s2) + { case POOL_UNPARSED: ret = (s1 == s2) ? 0 : 1; break; @@ -1716,10 +1757,11 @@ int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2) * To free the return value is required. */ static -char* remove_read_write(int len, const char* contents, int *rewritten_len) +char * +remove_read_write(int len, const char *contents, int *rewritten_len) { - char *rewritten_query; - char *rewritten_contents; + char *rewritten_query; + char *rewritten_contents; const char *name; const char *stmt; @@ -1730,8 +1772,8 @@ char* remove_read_write(int len, const char* contents, int *rewritten_len) *rewritten_len = len - strlen(stmt) + strlen(rewritten_query); if (len < *rewritten_len) { - ereport(ERROR, - (errmsg("invalid message length of transaction packet"))); + ereport(ERROR, + (errmsg("invalid message length of transaction packet"))); } rewritten_contents = palloc(*rewritten_len); @@ -1748,7 +1790,8 @@ char* remove_read_write(int len, const char* contents, int *rewritten_len) /* * Return true if current query is safe to cache. */ -bool pool_is_cache_safe(void) +bool +pool_is_cache_safe(void) { POOL_SESSION_CONTEXT *sc; @@ -1766,7 +1809,8 @@ bool pool_is_cache_safe(void) /* * Set safe to cache. */ -void pool_set_cache_safe(void) +void +pool_set_cache_safe(void) { POOL_SESSION_CONTEXT *sc; @@ -1783,7 +1827,8 @@ void pool_set_cache_safe(void) /* * Unset safe to cache. */ -void pool_unset_cache_safe(void) +void +pool_unset_cache_safe(void) { POOL_SESSION_CONTEXT *sc; @@ -1800,7 +1845,8 @@ void pool_unset_cache_safe(void) /* * Return true if current temporary query cache is exceeded */ -bool pool_is_cache_exceeded(void) +bool +pool_is_cache_exceeded(void) { POOL_SESSION_CONTEXT *sc; @@ -1820,7 +1866,8 @@ bool pool_is_cache_exceeded(void) /* * Set current temporary query cache is exceeded */ -void pool_set_cache_exceeded(void) +void +pool_set_cache_exceeded(void) { POOL_SESSION_CONTEXT *sc; @@ -1837,7 +1884,8 @@ void pool_set_cache_exceeded(void) /* * Unset current temporary query cache is exceeded */ -void pool_unset_cache_exceeded(void) +void +pool_unset_cache_exceeded(void) { POOL_SESSION_CONTEXT *sc; @@ -1860,10 +1908,11 @@ void pool_unset_cache_exceeded(void) * * Note that if the node is not a variable statement, returns false. */ -bool pool_is_transaction_read_only(Node *node) +bool +pool_is_transaction_read_only(Node *node) { ListCell *list_item; - bool ret = false; + bool ret = false; if (!IsA(node, VariableSetStmt)) return ret; @@ -1871,13 +1920,14 @@ bool pool_is_transaction_read_only(Node *node) /* * SET transaction_read_only TO on */ - if (((VariableSetStmt *)node)->kind == VAR_SET_VALUE && - !strcmp(((VariableSetStmt *)node)->name, "transaction_read_only")) + if (((VariableSetStmt *) node)->kind == VAR_SET_VALUE && + !strcmp(((VariableSetStmt *) node)->name, "transaction_read_only")) { - List *options = ((VariableSetStmt *)node)->args; + List *options = ((VariableSetStmt *) node)->args; + foreach(list_item, options) { - A_Const *v = (A_Const *)lfirst(list_item); + A_Const *v = (A_Const *) lfirst(list_item); switch (v->val.type) { @@ -1897,23 +1947,24 @@ bool pool_is_transaction_read_only(Node *node) } /* - * SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY - * SET TRANSACTION READ ONLY + * SET SESSION CHARACTERISTICS AS TRANSACTION READ ONLY SET TRANSACTION + * READ ONLY */ - else if (((VariableSetStmt *)node)->kind == VAR_SET_MULTI && - (!strcmp(((VariableSetStmt *)node)->name, "TRANSACTION") || - !strcmp(((VariableSetStmt *)node)->name, "SESSION CHARACTERISTICS"))) + else if (((VariableSetStmt *) node)->kind == VAR_SET_MULTI && + (!strcmp(((VariableSetStmt *) node)->name, "TRANSACTION") || + !strcmp(((VariableSetStmt *) node)->name, "SESSION CHARACTERISTICS"))) { - List *options = ((VariableSetStmt *)node)->args; + List *options = ((VariableSetStmt *) node)->args; + foreach(list_item, options) { - DefElem *opt = (DefElem *) lfirst(list_item); + DefElem *opt = (DefElem *) lfirst(list_item); if (!strcmp("transaction_read_only", opt->defname)) { - bool read_only; + bool read_only; - read_only = ((A_Const *)opt->arg)->val.val.ival; + read_only = ((A_Const *) opt->arg)->val.val.ival; if (read_only) { ret = true; diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c index 06d946473..697412180 100644 --- a/src/context/pool_session_context.c +++ b/src/context/pool_session_context.c @@ -1,7 +1,7 @@ /* -*-pgsql-c-*- */ /* * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -31,27 +31,28 @@ #include "protocol/pool_proto_modules.h" static POOL_SESSION_CONTEXT session_context_d; -static POOL_SESSION_CONTEXT *session_context = NULL; +static POOL_SESSION_CONTEXT * session_context = NULL; static void GetTranIsolationErrorCb(void *arg); static void init_sent_message_list(void); -static POOL_PENDING_MESSAGE *copy_pending_message(POOL_PENDING_MESSAGE *messag); -static void dump_sent_message(char *caller, POOL_SENT_MESSAGE *m); +static POOL_PENDING_MESSAGE * copy_pending_message(POOL_PENDING_MESSAGE * messag); +static void dump_sent_message(char *caller, POOL_SENT_MESSAGE * m); #ifdef PENDING_MESSAGE_DEBUG -static int Elevel = LOG; +static int Elevel = LOG; #else -static int Elevel = DEBUG2; +static int Elevel = DEBUG2; #endif /* * Initialize per session context */ -void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { session_context = &session_context_d; ProcessInfo *process_info; - int node_id; - int i; + int node_id; + int i; /* Clear session context memory */ memset(&session_context_d, 0, sizeof(session_context_d)); @@ -73,13 +74,13 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL * pool_incremnet_local_session_id(); /* Create memory context */ - /* TODO re-think about the parent for this context ??*/ + /* TODO re-think about the parent for this context ?? */ session_context->memory_context = AllocSetContextCreate(ProcessLoopContext, - "SessionContext", - ALLOCSET_SMALL_MINSIZE, - ALLOCSET_SMALL_INITSIZE, - ALLOCSET_SMALL_MAXSIZE); - + "SessionContext", + ALLOCSET_SMALL_MINSIZE, + ALLOCSET_SMALL_INITSIZE, + ALLOCSET_SMALL_MAXSIZE); + /* Initialize sent message list */ init_sent_message_list(); @@ -96,12 +97,12 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL * } else { - node_id = SL_MODE? PRIMARY_NODE_ID: MASTER_NODE_ID; + node_id = SL_MODE ? PRIMARY_NODE_ID : MASTER_NODE_ID; } session_context->load_balance_node_id = node_id; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { pool_coninfo(session_context->process_context->proc_id, pool_pool_index(), i)->load_balancing_node = node_id; @@ -136,9 +137,11 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL * #ifdef NOT_USED memset(&session_context->prep_where, 0, sizeof(session_context->prep_where)); session_context->prep_where.nelem = POOL_MAX_PREPARED_STATEMENTS; -#endif /* NOT_USED */ - /* Reset flag to indicate difference in number of affected tuples - * in UPDATE/DELETE. +#endif /* NOT_USED */ + + /* + * Reset flag to indicate difference in number of affected tuples in + * UPDATE/DELETE. */ session_context->mismatch_ntuples = false; @@ -163,7 +166,8 @@ void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL * /* * Destroy session context. */ -void pool_session_context_destroy(void) +void +pool_session_context_destroy(void) { if (session_context) { @@ -187,13 +191,14 @@ void pool_session_context_destroy(void) /* * Return session context */ -POOL_SESSION_CONTEXT *pool_get_session_context(bool noerror) +POOL_SESSION_CONTEXT * +pool_get_session_context(bool noerror) { if (!session_context && !noerror) { - ereport(FATAL, - (return_code(2), - errmsg("unable to get session context"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to get session context"))); } return session_context; } @@ -201,7 +206,8 @@ POOL_SESSION_CONTEXT *pool_get_session_context(bool noerror) /* * Return local session id */ -int pool_get_local_session_id(void) +int +pool_get_local_session_id(void) { return pool_get_session_context(false)->process_context->local_session_id; } @@ -209,7 +215,8 @@ int pool_get_local_session_id(void) /* * Return true if query is in progress */ -bool pool_is_query_in_progress(void) +bool +pool_is_query_in_progress(void) { return pool_get_session_context(false)->in_progress; } @@ -217,10 +224,11 @@ bool pool_is_query_in_progress(void) /* * Set query is in progress */ -void pool_set_query_in_progress(void) +void +pool_set_query_in_progress(void) { ereport(DEBUG5, - (errmsg("session context: setting query in progress. DONE"))); + (errmsg("session context: setting query in progress. DONE"))); pool_get_session_context(false)->in_progress = true; } @@ -228,19 +236,20 @@ void pool_set_query_in_progress(void) /* * Unset query is in progress */ -void pool_unset_query_in_progress(void) +void +pool_unset_query_in_progress(void) { POOL_SESSION_CONTEXT *s = pool_get_session_context(false); ereport(DEBUG5, - (errmsg("session context: unsetting query in progress. DONE"))); + (errmsg("session context: unsetting query in progress. DONE"))); s->in_progress = false; /* Restore where_to_send map if neccessary */ if (s->need_to_restore_where_to_send) { - memcpy(s->query_context->where_to_send,s->where_to_send_save, sizeof(s->where_to_send_save)); + memcpy(s->query_context->where_to_send, s->where_to_send_save, sizeof(s->where_to_send_save)); } s->need_to_restore_where_to_send = false; } @@ -248,7 +257,8 @@ void pool_unset_query_in_progress(void) /* * Return true if we skip reading from backends */ -bool pool_is_skip_reading_from_backends(void) +bool +pool_is_skip_reading_from_backends(void) { return pool_get_session_context(false)->skip_reading_from_backends; } @@ -256,7 +266,8 @@ bool pool_is_skip_reading_from_backends(void) /* * Set skip_reading_from_backends */ -void pool_set_skip_reading_from_backends(void) +void +pool_set_skip_reading_from_backends(void) { ereport(DEBUG5, (errmsg("session context: setting skip reading from backends. DONE"))); @@ -268,18 +279,20 @@ void pool_set_skip_reading_from_backends(void) /* * Unset skip_reading_from_backends */ -void pool_unset_skip_reading_from_backends(void) +void +pool_unset_skip_reading_from_backends(void) { ereport(DEBUG5, (errmsg("session context: clearing skip reading from backends. DONE"))); - + pool_get_session_context(false)->skip_reading_from_backends = false; } /* * Return true if we are doing extended query message */ -bool pool_is_doing_extended_query_message(void) +bool +pool_is_doing_extended_query_message(void) { return pool_get_session_context(false)->doing_extended_query_message; } @@ -287,29 +300,32 @@ bool pool_is_doing_extended_query_message(void) /* * Set doing_extended_query_message */ -void pool_set_doing_extended_query_message(void) +void +pool_set_doing_extended_query_message(void) { ereport(DEBUG5, (errmsg("session context: setting doing extended query messaging. DONE"))); - + pool_get_session_context(false)->doing_extended_query_message = true; } /* * Unset doing_extended_query_message */ -void pool_unset_doing_extended_query_message(void) +void +pool_unset_doing_extended_query_message(void) { ereport(DEBUG5, (errmsg("session context: clearing doing extended query messaging. DONE"))); - + pool_get_session_context(false)->doing_extended_query_message = false; } /* * Return true if backends ignore extended query message */ -bool pool_is_ignore_till_sync(void) +bool +pool_is_ignore_till_sync(void) { return pool_get_session_context(false)->ignore_till_sync; } @@ -317,18 +333,20 @@ bool pool_is_ignore_till_sync(void) /* * Set ignore_till_sync */ -void pool_set_ignore_till_sync(void) +void +pool_set_ignore_till_sync(void) { ereport(DEBUG5, (errmsg("session context: setting ignore till sync. DONE"))); - + pool_get_session_context(false)->ignore_till_sync = true; } /* * Unset ignore_till_sync */ -void pool_unset_ignore_till_sync(void) +void +pool_unset_ignore_till_sync(void) { ereport(DEBUG5, (errmsg("session context: clearing ignore till sync. DONE"))); @@ -339,9 +357,10 @@ void pool_unset_ignore_till_sync(void) /* * Remove a sent message */ -bool pool_remove_sent_message(char kind, const char *name) +bool +pool_remove_sent_message(char kind, const char *name) { - int i; + int i; POOL_SENT_MESSAGE_LIST *msglist; if (kind == 0 || name == NULL) @@ -365,7 +384,7 @@ bool pool_remove_sent_message(char kind, const char *name) if (i != msglist->size - 1) { - memmove(&msglist->sent_messages[i], &msglist->sent_messages[i+1], + memmove(&msglist->sent_messages[i], &msglist->sent_messages[i + 1], sizeof(POOL_SENT_MESSAGE *) * (msglist->size - i - 1)); } @@ -377,9 +396,10 @@ bool pool_remove_sent_message(char kind, const char *name) /* * Remove same kind of sent messages */ -void pool_remove_sent_messages(char kind) +void +pool_remove_sent_messages(char kind) { - int i; + int i; POOL_SENT_MESSAGE_LIST *msglist; msglist = &pool_get_session_context(false)->message_list; @@ -389,7 +409,7 @@ void pool_remove_sent_messages(char kind) if (msglist->sent_messages[i]->kind == kind) { if (pool_remove_sent_message(kind, msglist->sent_messages[i]->name)) - i--; /* for relocation by removing */ + i--; /* for relocation by removing */ } } } @@ -397,9 +417,10 @@ void pool_remove_sent_messages(char kind) /* * Destroy sent message */ -void pool_sent_message_destroy(POOL_SENT_MESSAGE *message) +void +pool_sent_message_destroy(POOL_SENT_MESSAGE * message) { - bool in_progress; + bool in_progress; POOL_QUERY_CONTEXT *qc = NULL; dump_sent_message("pool_sent_message_destroy", message); @@ -410,7 +431,7 @@ void pool_sent_message_destroy(POOL_SENT_MESSAGE *message) { if (message->contents) pfree(message->contents); - + if (message->name) pfree(message->name); @@ -422,12 +443,14 @@ void pool_sent_message_destroy(POOL_SENT_MESSAGE *message) if (can_query_context_destroy(message->query_context)) { pool_query_context_destroy(message->query_context); + /* * set in_progress flag, because pool_query_context_destroy() * unsets in_progress flag */ if (in_progress) pool_set_query_in_progress(); + /* * set query_context of session_context, because * pool_query_context_destroy() sets it to NULL. @@ -445,7 +468,8 @@ void pool_sent_message_destroy(POOL_SENT_MESSAGE *message) /* * Clear sent message list */ -void pool_clear_sent_message_list(void) +void +pool_clear_sent_message_list(void) { POOL_SENT_MESSAGE_LIST *msglist; @@ -457,7 +481,8 @@ void pool_clear_sent_message_list(void) } } -static void dump_sent_message(char *caller, POOL_SENT_MESSAGE *m) +static void +dump_sent_message(char *caller, POOL_SENT_MESSAGE * m) { ereport(DEBUG5, (errmsg("called by %s: sent message: address: %p kind: %c name: =%s= state:%d", @@ -472,18 +497,20 @@ static void dump_sent_message(char *caller, POOL_SENT_MESSAGE *m) * num_tsparams: number of timestamp parameters * name: prepared statement name or portal name */ -POOL_SENT_MESSAGE *pool_create_sent_message(char kind, int len, char *contents, - int num_tsparams, const char *name, - POOL_QUERY_CONTEXT *query_context) +POOL_SENT_MESSAGE * +pool_create_sent_message(char kind, int len, char *contents, + int num_tsparams, const char *name, + POOL_QUERY_CONTEXT * query_context) { POOL_SENT_MESSAGE *msg; if (!session_context) - ereport(ERROR, - (errmsg("unable to create message"), - errdetail("cannot get the session context"))); + ereport(ERROR, + (errmsg("unable to create message"), + errdetail("cannot get the session context"))); MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); + msg = palloc(sizeof(POOL_SENT_MESSAGE)); msg->kind = kind; msg->len = len; @@ -501,7 +528,8 @@ POOL_SENT_MESSAGE *pool_create_sent_message(char kind, int len, char *contents, /* * Add a sent message to sent message list */ -void pool_add_sent_message(POOL_SENT_MESSAGE *message) +void +pool_add_sent_message(POOL_SENT_MESSAGE * message) { POOL_SENT_MESSAGE *old_msg; POOL_SENT_MESSAGE_LIST *msglist; @@ -511,7 +539,7 @@ void pool_add_sent_message(POOL_SENT_MESSAGE *message) if (!message) { ereport(DEBUG5, - (errmsg("adding sent message to list"), + (errmsg("adding sent message to list"), errdetail("message is null"))); return; } @@ -537,12 +565,12 @@ void pool_add_sent_message(POOL_SENT_MESSAGE *message) { if (message->kind == 'B') ereport(DEBUG5, - (errmsg("adding sent message to list"), - errdetail("portal \"%s\" already exists",message->name))); + (errmsg("adding sent message to list"), + errdetail("portal \"%s\" already exists", message->name))); else ereport(DEBUG5, - (errmsg("adding sent message to list"), - errdetail("prepared statement \"%s\" already exists",message->name))); + (errmsg("adding sent message to list"), + errdetail("prepared statement \"%s\" already exists", message->name))); if (*message->name == '\0') pool_remove_sent_message(old_msg->kind, old_msg->name); @@ -568,9 +596,10 @@ void pool_add_sent_message(POOL_SENT_MESSAGE *message) /* * Get a sent message */ -POOL_SENT_MESSAGE *pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state) +POOL_SENT_MESSAGE * +pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state) { - int i; + int i; POOL_SENT_MESSAGE_LIST *msglist; msglist = &pool_get_session_context(false)->message_list; @@ -592,7 +621,8 @@ POOL_SENT_MESSAGE *pool_get_sent_message(char kind, const char *name, POOL_SENT_ /* * Set message state to POOL_SENT_MESSAGE_STATE to POOL_SENT_MESSAGE_CLOSED. */ -void pool_set_sent_message_state(POOL_SENT_MESSAGE *message) +void +pool_set_sent_message_state(POOL_SENT_MESSAGE * message) { ereport(DEBUG5, (errmsg("pool_set_sent_message_state: name:%s kind:%c previous state: %d", @@ -603,7 +633,8 @@ void pool_set_sent_message_state(POOL_SENT_MESSAGE *message) /* * We don't have a write query in this transaction yet. */ -void pool_unset_writing_transaction(void) +void +pool_unset_writing_transaction(void) { /* * If disable_transaction_on_write is 'always', then never turn off @@ -620,7 +651,8 @@ void pool_unset_writing_transaction(void) /* * We have a write query in this transaction. */ -void pool_set_writing_transaction(void) +void +pool_set_writing_transaction(void) { /* * If disable_transaction_on_write is 'off', then never turn on writing @@ -630,14 +662,15 @@ void pool_set_writing_transaction(void) { pool_get_session_context(false)->writing_transaction = true; ereport(DEBUG5, - (errmsg("session context: setting writing transaction. DONE"))); + (errmsg("session context: setting writing transaction. DONE"))); } } /* * Do we have a write query in this transaction? */ -bool pool_is_writing_transaction(void) +bool +pool_is_writing_transaction(void) { return pool_get_session_context(false)->writing_transaction; } @@ -645,18 +678,20 @@ bool pool_is_writing_transaction(void) /* * Error doesn't occur in this transaction yet. */ -void pool_unset_failed_transaction(void) +void +pool_unset_failed_transaction(void) { ereport(DEBUG5, (errmsg("session context: clearing failed transaction. DONE"))); - + pool_get_session_context(false)->failed_transaction = false; } /* * Error occurred in this transaction. */ -void pool_set_failed_transaction(void) +void +pool_set_failed_transaction(void) { ereport(DEBUG5, (errmsg("session context: setting failed transaction. DONE"))); @@ -667,7 +702,8 @@ void pool_set_failed_transaction(void) /* * Did error occur in this transaction? */ -bool pool_is_failed_transaction(void) +bool +pool_is_failed_transaction(void) { return pool_get_session_context(false)->failed_transaction; } @@ -675,7 +711,8 @@ bool pool_is_failed_transaction(void) /* * Forget transaction isolation mode */ -void pool_unset_transaction_isolation(void) +void +pool_unset_transaction_isolation(void) { ereport(DEBUG5, (errmsg("session context: clearing failed transaction. DONE"))); @@ -685,7 +722,8 @@ void pool_unset_transaction_isolation(void) /* * Set transaction isolation mode */ -void pool_set_transaction_isolation(POOL_TRANSACTION_ISOLATION isolation_level) +void +pool_set_transaction_isolation(POOL_TRANSACTION_ISOLATION isolation_level) { ereport(DEBUG5, (errmsg("session context: setting transaction isolation. DONE"))); @@ -695,7 +733,8 @@ void pool_set_transaction_isolation(POOL_TRANSACTION_ISOLATION isolation_level) /* * Get or return cached transaction isolation mode */ -POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void) +POOL_TRANSACTION_ISOLATION +pool_get_transaction_isolation(void) { POOL_SELECT_RESULT *res; POOL_TRANSACTION_ISOLATION ret; @@ -711,6 +750,7 @@ POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void) /* It seems cached result is usable. Return it. */ if (session_context->transaction_isolation != POOL_UNKNOWN) return session_context->transaction_isolation; + /* * Register a error context callback to throw proper context message */ @@ -722,7 +762,7 @@ POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void) /* No cached data is available. Ask backend. */ do_query(MASTER(session_context->backend), - "SELECT current_setting('transaction_isolation')", &res, MAJOR(session_context->backend)); + "SELECT current_setting('transaction_isolation')", &res, MAJOR(session_context->backend)); error_context_stack = callback.previous; @@ -760,10 +800,10 @@ POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void) else { ereport(WARNING, - (errmsg("error while getting transaction isolation, unknown transaction isolation level:%s",res->data[0]))); + (errmsg("error while getting transaction isolation, unknown transaction isolation level:%s", res->data[0]))); ret = POOL_UNKNOWN; - } + } free_select_result(res); @@ -773,7 +813,8 @@ POOL_TRANSACTION_ISOLATION pool_get_transaction_isolation(void) return ret; } -static void GetTranIsolationErrorCb(void *arg) +static void +GetTranIsolationErrorCb(void *arg) { errcontext("while getting transaction isolation"); } @@ -782,7 +823,8 @@ static void GetTranIsolationErrorCb(void *arg) /* * The command in progress has not succeeded yet. */ -void pool_unset_command_success(void) +void +pool_unset_command_success(void) { ereport(DEBUG5, (errmsg("session context: clearing transaction isolation. DONE"))); @@ -792,7 +834,8 @@ void pool_unset_command_success(void) /* * The command in progress has succeeded. */ -void pool_set_command_success(void) +void +pool_set_command_success(void) { ereport(DEBUG5, (errmsg("session context: setting command success. DONE"))); @@ -803,7 +846,8 @@ void pool_set_command_success(void) /* * Has the command in progress succeeded? */ -bool pool_is_command_success(void) +bool +pool_is_command_success(void) { return pool_get_session_context(false)->command_success; } @@ -811,17 +855,19 @@ bool pool_is_command_success(void) /* * Copy send map */ -void pool_copy_prep_where(bool *src, bool *dest) +void +pool_copy_prep_where(bool *src, bool *dest) { - memcpy(dest, src, sizeof(bool)*MAX_NUM_BACKENDS); + memcpy(dest, src, sizeof(bool) * MAX_NUM_BACKENDS); } #ifdef NOT_USED /* * Add to send map a PREPARED statement */ -void pool_add_prep_where(char *name, bool *map) +void +pool_add_prep_where(char *name, bool *map) { - int i; + int i; if (!session_context) { @@ -830,7 +876,7 @@ void pool_add_prep_where(char *name, bool *map) return; } - for (i=0;i<POOL_MAX_PREPARED_STATEMENTS;i++) + for (i = 0; i < POOL_MAX_PREPARED_STATEMENTS; i++) { if (*session_context->prep_where.name[i] == '\0') { @@ -846,16 +892,17 @@ void pool_add_prep_where(char *name, bool *map) /* * Search send map by PREPARED statement name */ -bool *pool_get_prep_where(char *name) +bool * +pool_get_prep_where(char *name) { - int i; + int i; if (!session_context) ereport(ERROR, (errmsg("pool_get_prep_where: session context is not initialized"))); - for (i=0;i<POOL_MAX_PREPARED_STATEMENTS;i++) + for (i = 0; i < POOL_MAX_PREPARED_STATEMENTS; i++) { if (!strcmp(session_context->prep_where.name[i], name)) { @@ -868,29 +915,31 @@ bool *pool_get_prep_where(char *name) /* * Remove PREPARED statement by name */ -void pool_delete_prep_where(char *name) +void +pool_delete_prep_where(char *name) { - int i; + int i; if (!session_context) ereport(ERROR, (errmsg("pool_delete_prep_where: session context is not initialized"))); - for (i=0;i<POOL_MAX_PREPARED_STATEMENTS;i++) + for (i = 0; i < POOL_MAX_PREPARED_STATEMENTS; i++) { if (!strcmp(session_context->prep_where.name[i], name)) { - memset(&session_context->prep_where.where_to_send[i], 0, sizeof(bool)*MAX_NUM_BACKENDS); + memset(&session_context->prep_where.where_to_send[i], 0, sizeof(bool) * MAX_NUM_BACKENDS); *session_context->prep_where.name[i] = '\0'; return; } } } -#endif /* NOT_USED */ +#endif /* NOT_USED */ /* * Initialize sent message list */ -static void init_sent_message_list(void) +static void +init_sent_message_list(void) { POOL_SENT_MESSAGE_LIST *msglist; @@ -909,10 +958,11 @@ static void init_sent_message_list(void) * Look for extended message list to check if given query context qc * is used. Returns true if it is not used. */ -bool can_query_context_destroy(POOL_QUERY_CONTEXT *qc) +bool +can_query_context_destroy(POOL_QUERY_CONTEXT * qc) { - int i; - int count = 0; + int i; + int count = 0; POOL_SENT_MESSAGE_LIST *msglist; ListCell *cell; ListCell *next; @@ -927,9 +977,9 @@ bool can_query_context_destroy(POOL_QUERY_CONTEXT *qc) if (count > 1) { ereport(DEBUG5, - (errmsg("checking if query context can be safely destroyed"), + (errmsg("checking if query context can be safely destroyed"), errdetail("query context %p is still used %d times in sent message list. query:\"%s\"", - qc, count,qc->original_query))); + qc, count, qc->original_query))); return false; } @@ -960,7 +1010,8 @@ bool can_query_context_destroy(POOL_QUERY_CONTEXT *qc) /* * Initialize pending message list */ -void pool_pending_messages_init(void) +void +pool_pending_messages_init(void) { if (!session_context) ereport(ERROR, @@ -972,7 +1023,8 @@ void pool_pending_messages_init(void) /* * Destroy pending message list */ -void pool_pending_messages_destroy(void) +void +pool_pending_messages_destroy(void) { ListCell *cell; POOL_PENDING_MESSAGE *msg; @@ -992,9 +1044,10 @@ void pool_pending_messages_destroy(void) /* * Create one message. */ -POOL_PENDING_MESSAGE *pool_pending_message_create(char kind, int len, char *contents) +POOL_PENDING_MESSAGE * +pool_pending_message_create(char kind, int len, char *contents) { - POOL_PENDING_MESSAGE* msg; + POOL_PENDING_MESSAGE *msg; MemoryContext old_context; if (!session_context) @@ -1007,33 +1060,33 @@ POOL_PENDING_MESSAGE *pool_pending_message_create(char kind, int len, char *cont switch (kind) { case 'P': - msg->type = POOL_PARSE; - break; + msg->type = POOL_PARSE; + break; case 'B': - msg->type = POOL_BIND; - break; + msg->type = POOL_BIND; + break; case 'E': - msg->type = POOL_EXECUTE; - break; + msg->type = POOL_EXECUTE; + break; case 'D': - msg->type = POOL_DESCRIBE; - break; + msg->type = POOL_DESCRIBE; + break; case 'C': - msg->type = POOL_CLOSE; - break; + msg->type = POOL_CLOSE; + break; case 'S': - msg->type = POOL_SYNC; - break; + msg->type = POOL_SYNC; + break; default: ereport(ERROR, (errmsg("pool_pending_message_create: unknow kind: %c", kind))); - break; + break; } if (len > 0) @@ -1061,12 +1114,13 @@ POOL_PENDING_MESSAGE *pool_pending_message_create(char kind, int len, char *cont * Set node_ids field of message which indicates which backend nodes the * message was sent. */ -void pool_pending_message_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context) +void +pool_pending_message_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context) { - int i; - int j = 0; + int i; + int j = 0; - for (i=0;i<MAX_NUM_BACKENDS;i++) + for (i = 0; i < MAX_NUM_BACKENDS; i++) { if (query_context->where_to_send[i]) { @@ -1092,9 +1146,10 @@ void pool_pending_message_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CON * Set where_to_send field in query_context from node_ids field of message * which indicates which backend nodes the message was sent. */ -void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context) +void +pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context) { - int i; + int i; POOL_SESSION_CONTEXT *s = pool_get_session_context(false); @@ -1105,7 +1160,7 @@ void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE* message, /* Rewrite where_to_send map */ memset(query_context->where_to_send, 0, sizeof(query_context->where_to_send)); - for (i=0;i<2;i++) + for (i = 0; i < 2; i++) { if (message->node_ids[i] != -1) { @@ -1117,7 +1172,8 @@ void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE* message, /* * Set query field of message. */ -void pool_pending_message_query_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context) +void +pool_pending_message_query_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context) { StrNCpy(message->query, query_context->original_query, sizeof(message->query)); } @@ -1125,9 +1181,10 @@ void pool_pending_message_query_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CO /* * Add one message to the tail of the list */ -void pool_pending_message_add(POOL_PENDING_MESSAGE* message) +void +pool_pending_message_add(POOL_PENDING_MESSAGE * message) { - POOL_PENDING_MESSAGE* msg; + POOL_PENDING_MESSAGE *msg; MemoryContext old_context; if (!session_context) @@ -1138,12 +1195,12 @@ void pool_pending_message_add(POOL_PENDING_MESSAGE* message) { case POOL_PARSE: StrNCpy(message->statement, message->contents, sizeof(message->statement)); - StrNCpy(message->query, message->contents+strlen(message->contents)+1, sizeof(message->query)); + StrNCpy(message->query, message->contents + strlen(message->contents) + 1, sizeof(message->query)); break; case POOL_BIND: StrNCpy(message->portal, message->contents, sizeof(message->portal)); - StrNCpy(message->statement, message->contents+strlen(message->contents)+1, sizeof(message->statement)); + StrNCpy(message->statement, message->contents + strlen(message->contents) + 1, sizeof(message->statement)); break; case POOL_EXECUTE: @@ -1153,9 +1210,9 @@ void pool_pending_message_add(POOL_PENDING_MESSAGE* message) case POOL_CLOSE: case POOL_DESCRIBE: if (*message->contents == 'S') - StrNCpy(message->statement, message->contents+1, sizeof(message->statement)); + StrNCpy(message->statement, message->contents + 1, sizeof(message->statement)); else - StrNCpy(message->portal, message->contents+1, sizeof(message->portal)); + StrNCpy(message->portal, message->contents + 1, sizeof(message->portal)); break; case POOL_SYNC: @@ -1188,7 +1245,8 @@ void pool_pending_message_add(POOL_PENDING_MESSAGE* message) * Return the message from the head of the list. If the list is not empty, a * copy of the message is returned. If the list is empty, returns NULL. */ -POOL_PENDING_MESSAGE *pool_pending_message_head_message(void) +POOL_PENDING_MESSAGE * +pool_pending_message_head_message(void) { ListCell *cell; POOL_PENDING_MESSAGE *message; @@ -1225,7 +1283,8 @@ POOL_PENDING_MESSAGE *pool_pending_message_head_message(void) * copy of the message is returned and the message is removed the message * list. If the list is empty, returns NULL. */ -POOL_PENDING_MESSAGE *pool_pending_message_pull_out(void) +POOL_PENDING_MESSAGE * +pool_pending_message_pull_out(void) { ListCell *cell; POOL_PENDING_MESSAGE *message; @@ -1264,7 +1323,8 @@ POOL_PENDING_MESSAGE *pool_pending_message_pull_out(void) * Try to find the first message specified by the message type in the message * list. If found, a copy of the message is returned. If not, returns NULL. */ -POOL_PENDING_MESSAGE *pool_pending_message_get(POOL_MESSAGE_TYPE type) +POOL_PENDING_MESSAGE * +pool_pending_message_get(POOL_MESSAGE_TYPE type) { ListCell *cell; ListCell *next; @@ -1300,7 +1360,8 @@ POOL_PENDING_MESSAGE *pool_pending_message_get(POOL_MESSAGE_TYPE type) * Get message specification (either statement ('S') or portal ('P')) from a * close message. */ -char pool_get_close_message_spec(POOL_PENDING_MESSAGE *msg) +char +pool_get_close_message_spec(POOL_PENDING_MESSAGE * msg) { return *msg->contents; } @@ -1309,16 +1370,17 @@ char pool_get_close_message_spec(POOL_PENDING_MESSAGE *msg) * Get statement or portal name from close message. * The returned pointer is within "msg". */ -char *pool_get_close_message_name(POOL_PENDING_MESSAGE *msg) +char * +pool_get_close_message_name(POOL_PENDING_MESSAGE * msg) { - return (msg->contents)+1; + return (msg->contents) + 1; } /* * Perform deep copy of POOL_PENDING_MESSAGE object in the current memory * context except the query context. */ -static POOL_PENDING_MESSAGE *copy_pending_message(POOL_PENDING_MESSAGE *message) +static POOL_PENDING_MESSAGE * copy_pending_message(POOL_PENDING_MESSAGE * message) { POOL_PENDING_MESSAGE *msg; @@ -1334,7 +1396,8 @@ static POOL_PENDING_MESSAGE *copy_pending_message(POOL_PENDING_MESSAGE *message) * Free POOL_PENDING_MESSAGE object in the current memory * context except the query context. */ -void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE *message) +void +pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE * message) { if (message == NULL) return; @@ -1348,7 +1411,8 @@ void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE *message) /* * Reset previous message. */ -void pool_pending_message_reset_previous_message(void) +void +pool_pending_message_reset_previous_message(void) { if (!session_context) { @@ -1362,7 +1426,8 @@ void pool_pending_message_reset_previous_message(void) /* * Set previous message. */ -void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message) +void +pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE * message) { if (!session_context) { @@ -1378,7 +1443,8 @@ void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message) * Get previous message. This actually returns the address of memory. Do not * try to free using pool_pending_message_free_pending_message(). */ -POOL_PENDING_MESSAGE *pool_pending_message_get_previous_message(void) +POOL_PENDING_MESSAGE * +pool_pending_message_get_previous_message(void) { if (!session_context) { @@ -1395,7 +1461,8 @@ POOL_PENDING_MESSAGE *pool_pending_message_get_previous_message(void) /* * Return true if there's any pending message. */ -bool pool_pending_message_exists(void) +bool +pool_pending_message_exists(void) { return list_length(session_context->pending_messages) > 0; } @@ -1404,10 +1471,12 @@ bool pool_pending_message_exists(void) * Convert enum pending message type to string. The returned string must not * be modified or freed. */ -const char *pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type) +const char * +pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type) { static const char *pending_msg_string[] = {"Parse", "Bind", "Execute", - "Descripbe", "Close", "Sync"}; + "Descripbe", "Close", "Sync"}; + if (type < 0 || type > POOL_SYNC) return "unknown type"; return pending_msg_string[type]; @@ -1417,18 +1486,19 @@ const char *pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type) * Check consistency the message type and backend message kind. * This function is intended to be used for debugging. */ -void pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind) +void +pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind) { - /* + /* * Backend response message sorted by POOL_MESSAGE_TYPE */ static char backend_response_kind[] = { - '1', /* POOL_PARSE, parse complete */ - '2', /* POOL_BIND, bind complete */ - '*', /* POOL_EXECUTE, skip checking */ - '*', /* POOL_DESCRIBE, skip checking */ - '3', /* POOL_CLOSE, close complete */ - 'Z' /* POOL_SYNC, ready for query */ + '1', /* POOL_PARSE, parse complete */ + '2', /* POOL_BIND, bind complete */ + '*', /* POOL_EXECUTE, skip checking */ + '*', /* POOL_DESCRIBE, skip checking */ + '3', /* POOL_CLOSE, close complete */ + 'Z' /* POOL_SYNC, ready for query */ }; if (type < POOL_PARSE || type > POOL_SYNC) @@ -1457,12 +1527,13 @@ void pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind) * returned message is a pointer to the message list. So do not free it using * pool_pending_message_free_pending_message. */ -POOL_PENDING_MESSAGE *pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT *qc) +POOL_PENDING_MESSAGE * +pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT * qc) { - List *msgs; + List *msgs; POOL_PENDING_MESSAGE *msg; - int len; - ListCell *cell; + int len; + ListCell *cell; if (!session_context) { @@ -1508,9 +1579,10 @@ POOL_PENDING_MESSAGE *pool_pending_message_find_lastest_by_query_context(POOL_QU * Get target backend id from pending message assuming that the destination for * the pending message is one of primary or standby node. */ -int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE *msg) +int +pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE * msg) { - int backend_id = -1; + int backend_id = -1; if (msg->node_ids[0] != -1) backend_id = msg->node_ids[0]; @@ -1526,7 +1598,8 @@ int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE *msg) /* * Dump whole pending message list */ -void dump_pending_message(void) +void +dump_pending_message(void) { ListCell *cell; ListCell *next; @@ -1560,18 +1633,20 @@ void dump_pending_message(void) /* * Set protocol major version number */ -void pool_set_major_version(int major) +void +pool_set_major_version(int major) { if (session_context) { - session_context->major = major; + session_context->major = major; } } /* * Get protocol major version number */ -int pool_get_major_version(void) +int +pool_get_major_version(void) { if (session_context) { @@ -1583,18 +1658,20 @@ int pool_get_major_version(void) /* * Set protocol minor version number */ -void pool_set_minor_version(int minor) +void +pool_set_minor_version(int minor) { if (session_context) { - session_context->minor = minor; + session_context->minor = minor; } } /* * Get protocol minor version number */ -int pool_get_minor_version(void) +int +pool_get_minor_version(void) { if (session_context) { @@ -1608,7 +1685,8 @@ int pool_get_minor_version(void) * Set preferred "master" node id. * Only used for SimpleForwardToFrontend. */ -void pool_set_preferred_master_node_id(int node_id) +void +pool_set_preferred_master_node_id(int node_id) { session_context->preferred_master_node_id = node_id; } @@ -1617,7 +1695,8 @@ void pool_set_preferred_master_node_id(int node_id) * Return preferred "master" node id. * Only used for SimpleForwardToFrontend. */ -int pool_get_preferred_master_node_id(void) +int +pool_get_preferred_master_node_id(void) { return session_context->preferred_master_node_id; } @@ -1626,7 +1705,8 @@ int pool_get_preferred_master_node_id(void) * Reset preferred "master" node id. * Only used for SimpleForwardToFrontend. */ -void pool_reset_preferred_master_node_id(void) +void +pool_reset_preferred_master_node_id(void) { session_context->preferred_master_node_id = -1; } diff --git a/src/include/auth/md5.h b/src/include/auth/md5.h index 87d23769f..6ea08ad8f 100644 --- a/src/include/auth/md5.h +++ b/src/include/auth/md5.h @@ -23,7 +23,7 @@ #define WD_AUTH_HASH_LEN 64 -extern int pool_md5_hash(const void *buff, size_t len, char *hexsum); -extern int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); +extern int pool_md5_hash(const void *buff, size_t len, char *hexsum); +extern int pool_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); extern void bytesToHex(char *b, int len, char *s); #endif diff --git a/src/include/auth/pool_hba.h b/src/include/auth/pool_hba.h index 6a22afd1c..77cad9d7f 100644 --- a/src/include/auth/pool_hba.h +++ b/src/include/auth/pool_hba.h @@ -34,18 +34,18 @@ typedef enum UserAuth { uaImplicitReject, uaReject, - /* uaKrb4, */ - /* uaKrb5, */ + /* uaKrb4, */ + /* uaKrb5, */ uaTrust, - /* uaIdent, */ + /* uaIdent, */ uaPassword, - /* uaCrypt, */ + /* uaCrypt, */ uaCert, uaMD5, uaSCRAM #ifdef USE_PAM ,uaPAM -#endif /* USE_PAM */ +#endif /* USE_PAM */ } UserAuth; @@ -67,21 +67,21 @@ typedef enum IPCompareMethod struct HbaLine { - int linenumber; - char *rawline; - ConnType conntype; - List *databases; - List *users; + int linenumber; + char *rawline; + ConnType conntype; + List *databases; + List *users; struct sockaddr_storage addr; struct sockaddr_storage mask; IPCompareMethod ip_cmp_method; - char *hostname; - UserAuth auth_method; - char *pamservice; + char *hostname; + UserAuth auth_method; + char *pamservice; bool pam_use_hostname; }; extern bool load_hba(char *hbapath); -extern void ClientAuthentication(POOL_CONNECTION *frontend); +extern void ClientAuthentication(POOL_CONNECTION * frontend); -#endif /* POOL_HBA_H */ +#endif /* POOL_HBA_H */ diff --git a/src/include/auth/pool_passwd.h b/src/include/auth/pool_passwd.h index 71f059379..796b59586 100644 --- a/src/include/auth/pool_passwd.h +++ b/src/include/auth/pool_passwd.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -40,10 +40,13 @@ #define PASSWORD_SCRAM_PREFIX "SCRAM-SHA-256$" #define PASSWORD_TEXT_PREFIX "TEXT" -typedef enum { - POOL_PASSWD_R, /* open pool_passwd in read only mode. used by pgpool-II child main process */ - POOL_PASSWD_RW, /* open pool_passwd in read/write mode. used by pg_md5 command */ -} POOL_PASSWD_MODE; +typedef enum +{ + POOL_PASSWD_R, /* open pool_passwd in read only mode. used by + * pgpool-II child main process */ + POOL_PASSWD_RW, /* open pool_passwd in read/write mode. used + * by pg_md5 command */ +} POOL_PASSWD_MODE; typedef enum PasswordType { @@ -56,22 +59,22 @@ typedef enum PasswordType typedef struct UserPassword { - char *userName; - char *password; + char *userName; + char *password; PasswordType passwordType; -}UserPassword; +} UserPassword; typedef struct PasswordMapping { UserPassword pgpoolUser; UserPassword backendUser; - bool mappedUser; -}PasswordMapping; + bool mappedUser; +} PasswordMapping; -extern PasswordMapping *pool_get_user_credentials(char *username); +extern PasswordMapping * pool_get_user_credentials(char *username); extern PasswordType get_password_type(const char *shadow_pass); extern void pool_init_pool_passwd(char *pool_passwd_filename, POOL_PASSWD_MODE mode); -extern int pool_create_passwdent(char *username, char *passwd); +extern int pool_create_passwdent(char *username, char *passwd); extern char *pool_get_passwd(char *username); extern void pool_delete_passwdent(char *username); extern void pool_finish_pool_passwd(void); @@ -79,5 +82,5 @@ extern void pool_reopen_passwd_file(void); extern char *get_decrypted_password(const char *shadow_pass); extern char *read_pool_key(char *key_file_path); extern char *get_pgpool_config_user_password(char *username, char *password_in_config); -extern void delete_passwordMapping(PasswordMapping *pwdMapping); -#endif /* POOL_PASSWD_H */ +extern void delete_passwordMapping(PasswordMapping * pwdMapping); +#endif /* POOL_PASSWD_H */ diff --git a/src/include/auth/scram.h b/src/include/auth/scram.h index 71222d47c..883ab1442 100644 --- a/src/include/auth/scram.h +++ b/src/include/auth/scram.h @@ -58,7 +58,7 @@ extern bool scram_verify_plain_password(const char *username, extern void *pg_fe_scram_init(const char *username, const char *password); extern void pg_fe_scram_exchange(void *opaq, char *input, int inputlen, char **output, int *outputlen, - bool *done, bool *success); + bool *done, bool *success); extern void pg_fe_scram_free(void *opaq); extern char *pg_fe_scram_build_verifier(const char *password); diff --git a/src/include/context/pool_process_context.h b/src/include/context/pool_process_context.h index 2e7863b0c..d57bb0511 100644 --- a/src/include/context/pool_process_context.h +++ b/src/include/context/pool_process_context.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2015 PgPool Global Development Group @@ -31,44 +31,46 @@ * Child process context: * Manages per pgpool child process context */ -typedef struct { +typedef struct +{ /* * process start time, info on connection to backend etc. */ - ProcessInfo *process_info; - int proc_id; /* Index to process table(ProcessInfo) (!= UNIX's PID) */ + ProcessInfo *process_info; + int proc_id; /* Index to process table(ProcessInfo) (!= + * UNIX's PID) */ /* - * PostgreSQL server description. Placed on shared memory. - * Includes backend up/down info, hostname, data directory etc. + * PostgreSQL server description. Placed on shared memory. Includes + * backend up/down info, hostname, data directory etc. */ BackendDesc *backend_desc; - int local_session_id; /* local session id */ + int local_session_id; /* local session id */ pool_sighandler_t last_alarm_handler; - time_t last_alarm_time; + time_t last_alarm_time; unsigned int last_alarm_second; unsigned int undo_alarm_second; -} POOL_PROCESS_CONTEXT; +} POOL_PROCESS_CONTEXT; extern void pool_init_process_context(void); -extern POOL_PROCESS_CONTEXT *pool_get_process_context(void); -extern ProcessInfo *pool_get_my_process_info(void); +extern POOL_PROCESS_CONTEXT * pool_get_process_context(void); +extern ProcessInfo * pool_get_my_process_info(void); extern void pool_incremnet_local_session_id(void); -extern int pool_coninfo_size(void); -extern int pool_coninfo_num(void); -extern ConnectionInfo *pool_coninfo(int child, int connection_pool, int backend); -extern ConnectionInfo *pool_coninfo_pid(int pid, int connection_pool, int backend); +extern int pool_coninfo_size(void); +extern int pool_coninfo_num(void); +extern ConnectionInfo * pool_coninfo(int child, int connection_pool, int backend); +extern ConnectionInfo * pool_coninfo_pid(int pid, int connection_pool, int backend); extern void pool_coninfo_set_frontend_connected(int proc_id, int pool_index); extern void pool_coninfo_unset_frontend_connected(int proc_id, int pool_index); -extern ConnectionInfo* pool_coninfo_backend_pid(int backend_pid, int* backend_node_id); -extern void pool_set_connection_will_be_terminated(ConnectionInfo* connInfo); -extern void pool_unset_connection_will_be_terminated(ConnectionInfo* connInfo); +extern ConnectionInfo * pool_coninfo_backend_pid(int backend_pid, int *backend_node_id); +extern void pool_set_connection_will_be_terminated(ConnectionInfo * connInfo); +extern void pool_unset_connection_will_be_terminated(ConnectionInfo * connInfo); extern void pool_alarm(pool_sighandler_t handler, unsigned int second); extern void pool_undo_alarm(void); -#endif /* POOL_PROCESS_CONTEXT_H */ +#endif /* POOL_PROCESS_CONTEXT_H */ diff --git a/src/include/context/pool_query_context.h b/src/include/context/pool_query_context.h index ebf0de408..55e8b873a 100644 --- a/src/include/context/pool_query_context.h +++ b/src/include/context/pool_query_context.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2017 PgPool Global Development Group @@ -38,77 +38,86 @@ * transition order is: * UNPARSED < PARSE_COMPLETE < BIND_COMPLETE < EXECUTE_COMPLETE */ -typedef enum { +typedef enum +{ POOL_UNPARSED, POOL_PARSE_COMPLETE, POOL_BIND_COMPLETE, POOL_EXECUTE_COMPLETE -} POOL_QUERY_STATE; +} POOL_QUERY_STATE; /* * Query context: * Manages per query context */ -typedef struct { - char *original_query; /* original query string */ - char *rewritten_query; /* rewritten query string if any */ - int original_length; /* original query length which contains '\0' */ - int rewritten_length; /* rewritten query length which contains '\0' if any */ - Node *parse_tree; /* raw parser output if any */ - Node *rewritten_parse_tree; /* rewritten raw parser output if any */ - bool where_to_send[MAX_NUM_BACKENDS]; /* DB node map to send query */ - int virtual_master_node_id; /* the 1st DB node to send query */ - POOL_QUERY_STATE query_state[MAX_NUM_BACKENDS]; /* for extended query protocol */ - bool is_cache_safe; /* true if SELECT is safe to cache */ +typedef struct +{ + char *original_query; /* original query string */ + char *rewritten_query; /* rewritten query string if any */ + int original_length; /* original query length which contains + * '\0' */ + int rewritten_length; /* rewritten query length which contains + * '\0' if any */ + Node *parse_tree; /* raw parser output if any */ + Node *rewritten_parse_tree; /* rewritten raw parser output if any */ + bool where_to_send[MAX_NUM_BACKENDS]; /* DB node map to send + * query */ + int virtual_master_node_id; /* the 1st DB node to send query */ + POOL_QUERY_STATE query_state[MAX_NUM_BACKENDS]; /* for extended query + * protocol */ + bool is_cache_safe; /* true if SELECT is safe to cache */ POOL_TEMP_QUERY_CACHE *temp_cache; /* temporary cache */ - bool is_multi_statement; /* true if multi statement query */ - int dboid; /* DB oid which is used at DROP DATABASE */ - char *query_w_hex; /* original_query with bind message hex which used for committing cache of extended query */ - bool is_parse_error; /* if true, we could not parse the original - * query and parsed node is actually a dummy query. - */ - int num_original_params; /* number of parameters in original query */ - ConnectionInfo *pg_terminate_backend_conn; - /* pointer to the shared memory connection info object - * referred by pg_terminate_backend() function. - * we need this to reset the flag after executing - * the pg_terminate_backend query, especially for the - * case when the query gets fail on the backend. - */ + bool is_multi_statement; /* true if multi statement query */ + int dboid; /* DB oid which is used at DROP DATABASE */ + char *query_w_hex; /* original_query with bind message hex which + * used for committing cache of extended query */ + bool is_parse_error; /* if true, we could not parse the original + * query and parsed node is actually a dummy + * query. */ + int num_original_params; /* number of parameters in original + * query */ + ConnectionInfo *pg_terminate_backend_conn; - bool skip_cache_commit; /* In streaming replication mode and extended query, - * do not commit cache if this flag is true. - */ + /* + * pointer to the shared memory connection info object referred by + * pg_terminate_backend() function. we need this to reset the flag after + * executing the pg_terminate_backend query, especially for the case when + * the query gets fail on the backend. + */ + + bool skip_cache_commit; /* In streaming replication mode and + * extended query, do not commit cache if + * this flag is true. */ MemoryContext memory_context; /* memory context for query context */ -} POOL_QUERY_CONTEXT; +} POOL_QUERY_CONTEXT; -extern POOL_QUERY_CONTEXT *pool_init_query_context(void); -extern void pool_query_context_destroy(POOL_QUERY_CONTEXT *query_context); -extern POOL_QUERY_CONTEXT *pool_query_context_shallow_copy(POOL_QUERY_CONTEXT *query_context); -extern void pool_start_query(POOL_QUERY_CONTEXT *query_context, char *query, int len, Node *node); -extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); -extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); -extern bool pool_is_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); -extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); -extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT *query_context, int node_id); -extern void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT *query_context); -extern void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT *query_context); -extern bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT *query_context); -extern void pool_where_to_send(POOL_QUERY_CONTEXT *query_context, char *query, Node *node); -extern POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT *query_context, int send_type, int node_id); -extern POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT *query_context, char *kind, int len, char *contents, int send_type, int node_id, bool nowait); +extern POOL_QUERY_CONTEXT * pool_init_query_context(void); +extern void pool_query_context_destroy(POOL_QUERY_CONTEXT * query_context); +extern POOL_QUERY_CONTEXT * pool_query_context_shallow_copy(POOL_QUERY_CONTEXT * query_context); +extern void pool_start_query(POOL_QUERY_CONTEXT * query_context, char *query, int len, Node *node); +extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); +extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); +extern bool pool_is_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); +extern void pool_set_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); +extern void pool_unset_node_to_be_sent(POOL_QUERY_CONTEXT * query_context, int node_id); +extern void pool_clear_node_to_be_sent(POOL_QUERY_CONTEXT * query_context); +extern void pool_setall_node_to_be_sent(POOL_QUERY_CONTEXT * query_context); +extern bool pool_multi_node_to_be_sent(POOL_QUERY_CONTEXT * query_context); +extern void pool_where_to_send(POOL_QUERY_CONTEXT * query_context, char *query, Node *node); +extern POOL_STATUS pool_send_and_wait(POOL_QUERY_CONTEXT * query_context, int send_type, int node_id); +extern POOL_STATUS pool_extended_send_and_wait(POOL_QUERY_CONTEXT * query_context, char *kind, int len, char *contents, int send_type, int node_id, bool nowait); extern Node *pool_get_parse_tree(void); extern char *pool_get_query_string(void); extern bool is_set_transaction_serializable(Node *node); extern bool is_start_transaction_query(Node *node); extern bool is_read_write(TransactionStmt *node); extern bool is_serializable(TransactionStmt *node); -extern bool pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT *query_context); +extern bool pool_need_to_treat_as_if_default_transaction(POOL_QUERY_CONTEXT * query_context); extern bool is_savepoint_query(Node *node); extern bool is_2pc_transaction_query(Node *node); -extern void pool_set_query_state(POOL_QUERY_CONTEXT *query_context, POOL_QUERY_STATE state); -extern int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2); +extern void pool_set_query_state(POOL_QUERY_CONTEXT * query_context, POOL_QUERY_STATE state); +extern int statecmp(POOL_QUERY_STATE s1, POOL_QUERY_STATE s2); extern bool pool_is_cache_safe(void); extern void pool_set_cache_safe(void); extern void pool_unset_cache_safe(void); @@ -116,5 +125,5 @@ extern bool pool_is_cache_exceeded(void); extern void pool_set_cache_exceeded(void); extern void pool_unset_cache_exceeded(void); extern bool pool_is_transaction_read_only(Node *node); -extern void pool_force_query_node_to_backend(POOL_QUERY_CONTEXT *query_context, int backend_id); -#endif /* POOL_QUERY_CONTEXT_H */ +extern void pool_force_query_node_to_backend(POOL_QUERY_CONTEXT * query_context, int backend_id); +#endif /* POOL_QUERY_CONTEXT_H */ diff --git a/src/include/context/pool_session_context.h b/src/include/context/pool_session_context.h index af5ee4972..79016a386 100644 --- a/src/include/context/pool_session_context.h +++ b/src/include/context/pool_session_context.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -36,65 +36,72 @@ /* * Transaction isolation mode */ -typedef enum { +typedef enum +{ POOL_UNKNOWN, /* Unknown. Need to ask backend */ POOL_READ_UNCOMMITTED, /* Read uncommitted */ POOL_READ_COMMITTED, /* Read committed */ POOL_REPEATABLE_READ, /* Rpeatable read */ POOL_SERIALIZABLE /* Serializable */ -} POOL_TRANSACTION_ISOLATION; +} POOL_TRANSACTION_ISOLATION; /* * Return values for pool_use_sync_map */ -typedef enum { +typedef enum +{ POOL_IGNORE_SYNC_MAP, /* Please ignore sync map */ POOL_SYNC_MAP_IS_VALID, /* Sync map is valid */ POOL_SYNC_MAP_EMPTY, /* Sync map is empty */ -} POOL_SYNC_MAP_STATE; +} POOL_SYNC_MAP_STATE; /* * Status of sent message */ -typedef enum { +typedef enum +{ POOL_SENT_MESSAGE_CREATED, /* initial state of sent meesage */ - POOL_SENT_MESSAGE_CLOSED /* sent meesage closed but close complete message has not arrived yet */ -} POOL_SENT_MESSAGE_STATE; + POOL_SENT_MESSAGE_CLOSED /* sent meesage closed but close complete + * message has not arrived yet */ +} POOL_SENT_MESSAGE_STATE; + /* * Message content of extended query */ -typedef struct { +typedef struct +{ /* * One of 'P':Parse, 'B':Bind or 'Q':Query (PREPARE). If kind = 'B', it * is assumed that the message is a portal. */ - char kind; + char kind; - int len; /* message length in host byte order */ - char *contents; - POOL_SENT_MESSAGE_STATE state; /* message state */ - int num_tsparams; - char *name; /* object name of prepared statement or portal */ + int len; /* message length in host byte order */ + char *contents; + POOL_SENT_MESSAGE_STATE state; /* message state */ + int num_tsparams; + char *name; /* object name of prepared statement or portal */ POOL_QUERY_CONTEXT *query_context; + /* * Following members are only used when memcache is enabled. */ - bool is_cache_safe; /* true if the query can be cached */ - int param_offset; /* Offset from contents where actual bind - * parameters are stored. - * This is meaningful only when is_cache_safe is true. - */ -} POOL_SENT_MESSAGE; + bool is_cache_safe; /* true if the query can be cached */ + int param_offset; /* Offset from contents where actual bind + * parameters are stored. This is meaningful + * only when is_cache_safe is true. */ +} POOL_SENT_MESSAGE; /* * List of POOL_SENT_MESSAGE (XXX this should have been implemented using a * list, rather than an array) */ -typedef struct { - int capacity; /* capacity of list */ - int size; /* number of elements */ +typedef struct +{ + int capacity; /* capacity of list */ + int size; /* number of elements */ POOL_SENT_MESSAGE **sent_messages; -} POOL_SENT_MESSAGE_LIST; +} POOL_SENT_MESSAGE_LIST; /* * Received message queue used in extended query/streaming replication mode. @@ -108,29 +115,35 @@ typedef struct { * The memory used for the queue lives in the session context mememory. */ -typedef enum { +typedef enum +{ POOL_PARSE = 0, POOL_BIND, POOL_EXECUTE, POOL_DESCRIBE, POOL_CLOSE, POOL_SYNC -} POOL_MESSAGE_TYPE; +} POOL_MESSAGE_TYPE; -typedef struct { +typedef struct +{ POOL_MESSAGE_TYPE type; - char *contents; /* message packet contents excluding message kind */ - int contents_len; /* message packet length */ - char query[QUERY_STRING_BUFFER_LEN]; /* copy of original query */ - char statement[MAX_IDENTIFIER_LEN]; /* prepared statment name if any */ - char portal[MAX_IDENTIFIER_LEN]; /* portal name if any */ - bool is_rows_returned; /* true if the message could produce row data */ - bool not_forward_to_frontend; /* Do not forward response from backend to frontend. - * This is used by parse_before_bind() - */ - int node_ids[2]; /* backend node ids this message was sent to. -1 means no message was sent. */ + char *contents; /* message packet contents excluding message + * kind */ + int contents_len; /* message packet length */ + char query[QUERY_STRING_BUFFER_LEN]; /* copy of original query */ + char statement[MAX_IDENTIFIER_LEN]; /* prepared statment name if + * any */ + char portal[MAX_IDENTIFIER_LEN]; /* portal name if any */ + bool is_rows_returned; /* true if the message could produce row + * data */ + bool not_forward_to_frontend; /* Do not forward response from + * backend to frontend. This is + * used by parse_before_bind() */ + int node_ids[2]; /* backend node ids this message was sent to. + * -1 means no message was sent. */ POOL_QUERY_CONTEXT *query_context; /* query context */ -} POOL_PENDING_MESSAGE; +} POOL_PENDING_MESSAGE; /* Return true if node_id is one of node_ids */ #define IS_SENT_NODE_ID(msg, node_id) (msg->node_ids[0] == node_id || msg->node_ids[1] == node_id) @@ -138,42 +151,45 @@ typedef struct { /* * Per session context: */ -typedef struct { - POOL_PROCESS_CONTEXT *process_context; /* belonging process */ +typedef struct +{ + POOL_PROCESS_CONTEXT *process_context; /* belonging process */ POOL_CONNECTION *frontend; /* connection to frontend */ - POOL_CONNECTION_POOL *backend; /* connection to backends */ + POOL_CONNECTION_POOL *backend; /* connection to backends */ - /* If true, we are waiting for backend response. For SELECT this - * flags should be kept until all responses are returned from - * backend. i.e. until "Read for Query" packet. + /* + * If true, we are waiting for backend response. For SELECT this flags + * should be kept until all responses are returned from backend. i.e. + * until "Read for Query" packet. */ - bool in_progress; + bool in_progress; /* If true, we are doing extended query message */ - bool doing_extended_query_message; + bool doing_extended_query_message; - /* If true, we have rewritten where_to_send map in the current query + /* + * If true, we have rewritten where_to_send map in the current query * context. pool_unset_query_in_progress() should restore the data from * where_to_send_save. For now, this is only necessary while doing * extended query protocol and in streaming replication mode. */ - bool need_to_restore_where_to_send; - bool where_to_send_save[MAX_NUM_BACKENDS]; + bool need_to_restore_where_to_send; + bool where_to_send_save[MAX_NUM_BACKENDS]; /* If true, the command in progress has finished successfully. */ - bool command_success; + bool command_success; /* If true, write query has been appeared in this transaction */ - bool writing_transaction; + bool writing_transaction; /* If true, error occurred in this transaction */ - bool failed_transaction; + bool failed_transaction; /* If true, we skip reading from backends */ - bool skip_reading_from_backends; + bool skip_reading_from_backends; /* ignore any command until Sync message */ - bool ignore_till_sync; + bool ignore_till_sync; /* * Transaction isolation mode. @@ -181,15 +197,15 @@ typedef struct { POOL_TRANSACTION_ISOLATION transaction_isolation; /* - * Associated query context, only used for non-extended - * protocol. In extended protocol, the query context resides in - * "PreparedStatementList *pstmt_list" (see below). + * Associated query context, only used for non-extended protocol. In + * extended protocol, the query context resides in "PreparedStatementList + * *pstmt_list" (see below). */ POOL_QUERY_CONTEXT *query_context; #ifdef NOT_USED /* where to send map for PREPARE/EXECUTE/DEALLOCATE */ POOL_PREPARED_SEND_MAP prep_where; -#endif /* NOT_USED */ +#endif /* NOT_USED */ MemoryContext memory_context; /* memory context for session */ /* message which doesn't receive complete message */ @@ -197,59 +213,59 @@ typedef struct { POOL_SENT_MESSAGE_LIST message_list; - int load_balance_node_id; /* selected load balance node id */ + int load_balance_node_id; /* selected load balance node id */ /* - * If true, UPDATE/DELETE caused difference in number of affected - * tuples in backends. - */ - bool mismatch_ntuples; + * If true, UPDATE/DELETE caused difference in number of affected tuples + * in backends. + */ + bool mismatch_ntuples; /* - * If mismatch_ntuples true, this array holds the number of - * affected tuples of each node. - * -1 for down nodes. + * If mismatch_ntuples true, this array holds the number of affected + * tuples of each node. -1 for down nodes. */ - int ntuples[MAX_NUM_BACKENDS]; + int ntuples[MAX_NUM_BACKENDS]; /* * If true, we are executing reset query list. */ - bool reset_context; + bool reset_context; /* * Query cache management area */ POOL_QUERY_CACHE_ARRAY *query_cache_array; /* pending SELECT results */ - long long int num_selects; /* number of successful SELECTs in this transaction */ + long long int num_selects; /* number of successful SELECTs in this + * transaction */ /* * Parse/Bind/Decribe/Execute/Close message queue. */ - List *pending_messages; + List *pending_messages; /* * The last pending message. Reset at Ready for query. Note that this is * a shallow copy of pending message. Once the are is reset, * previos_message_exists is set to false. */ - bool previous_message_exists; + bool previous_message_exists; POOL_PENDING_MESSAGE previous_message; /* Protocol major version number */ - int major; + int major; /* Protocol minor version number */ - int minor; + int minor; #ifdef NOT_USED /* Preferred "master" node id. Only used for SimpleForwardToFrontend. */ - int preferred_master_node_id; + int preferred_master_node_id; #endif -} POOL_SESSION_CONTEXT; +} POOL_SESSION_CONTEXT; -extern void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void pool_init_session_context(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); extern void pool_session_context_destroy(void); -extern POOL_SESSION_CONTEXT *pool_get_session_context(bool noerror); -extern int pool_get_local_session_id(void); +extern POOL_SESSION_CONTEXT * pool_get_session_context(bool noerror); +extern int pool_get_local_session_id(void); extern bool pool_is_query_in_progress(void); extern void pool_set_query_in_progress(void); extern void pool_unset_query_in_progress(void); @@ -262,16 +278,16 @@ extern void pool_unset_doing_extended_query_message(void); extern bool pool_is_ignore_till_sync(void); extern void pool_set_ignore_till_sync(void); extern void pool_unset_ignore_till_sync(void); -extern POOL_SENT_MESSAGE *pool_create_sent_message(char kind, int len, char *contents, - int num_tsparams, const char *name, - POOL_QUERY_CONTEXT *query_context); -extern void pool_add_sent_message(POOL_SENT_MESSAGE *message); +extern POOL_SENT_MESSAGE * pool_create_sent_message(char kind, int len, char *contents, + int num_tsparams, const char *name, + POOL_QUERY_CONTEXT * query_context); +extern void pool_add_sent_message(POOL_SENT_MESSAGE * message); extern bool pool_remove_sent_message(char kind, const char *name); extern void pool_remove_sent_messages(char kind); extern void pool_clear_sent_message_list(void); -extern void pool_sent_message_destroy(POOL_SENT_MESSAGE *message); -extern POOL_SENT_MESSAGE *pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state); -extern void pool_set_sent_message_state(POOL_SENT_MESSAGE *message); +extern void pool_sent_message_destroy(POOL_SENT_MESSAGE * message); +extern POOL_SENT_MESSAGE * pool_get_sent_message(char kind, const char *name, POOL_SENT_MESSAGE_STATE state); +extern void pool_set_sent_message_state(POOL_SENT_MESSAGE * message); extern void pool_unset_writing_transaction(void); extern void pool_set_writing_transaction(void); extern bool pool_is_writing_transaction(void); @@ -285,35 +301,35 @@ extern void pool_unset_command_success(void); extern void pool_set_command_success(void); extern bool pool_is_command_success(void); extern void pool_copy_prep_where(bool *src, bool *dest); -extern bool can_query_context_destroy(POOL_QUERY_CONTEXT *qc); -extern void pool_pending_messages_init (void); +extern bool can_query_context_destroy(POOL_QUERY_CONTEXT * qc); +extern void pool_pending_messages_init(void); extern void pool_pending_messages_destroy(void); -extern POOL_PENDING_MESSAGE *pool_pending_message_create(char kind, int len, char *contents); -extern void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE *message); -extern void pool_pending_message_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context); -extern void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context); -extern void pool_pending_message_query_set(POOL_PENDING_MESSAGE* message, POOL_QUERY_CONTEXT *query_context); -extern void pool_pending_message_add(POOL_PENDING_MESSAGE* message); -extern POOL_PENDING_MESSAGE *pool_pending_message_head_message(void); -extern POOL_PENDING_MESSAGE *pool_pending_message_pull_out(void); -extern POOL_PENDING_MESSAGE *pool_pending_message_get(POOL_MESSAGE_TYPE type); -extern char pool_get_close_message_spec(POOL_PENDING_MESSAGE *msg); -extern char *pool_get_close_message_name(POOL_PENDING_MESSAGE *msg); +extern POOL_PENDING_MESSAGE * pool_pending_message_create(char kind, int len, char *contents); +extern void pool_pending_message_free_pending_message(POOL_PENDING_MESSAGE * message); +extern void pool_pending_message_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); +extern void pool_pending_message_query_context_dest_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); +extern void pool_pending_message_query_set(POOL_PENDING_MESSAGE * message, POOL_QUERY_CONTEXT * query_context); +extern void pool_pending_message_add(POOL_PENDING_MESSAGE * message); +extern POOL_PENDING_MESSAGE * pool_pending_message_head_message(void); +extern POOL_PENDING_MESSAGE * pool_pending_message_pull_out(void); +extern POOL_PENDING_MESSAGE * pool_pending_message_get(POOL_MESSAGE_TYPE type); +extern char pool_get_close_message_spec(POOL_PENDING_MESSAGE * msg); +extern char *pool_get_close_message_name(POOL_PENDING_MESSAGE * msg); extern void pool_pending_message_reset_previous_message(void); -extern void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE *message); -extern POOL_PENDING_MESSAGE *pool_pending_message_get_previous_message(void); +extern void pool_pending_message_set_previous_message(POOL_PENDING_MESSAGE * message); +extern POOL_PENDING_MESSAGE * pool_pending_message_get_previous_message(void); extern bool pool_pending_message_exists(void); extern const char *pool_pending_message_type_to_string(POOL_MESSAGE_TYPE type); extern void pool_check_pending_message_and_reply(POOL_MESSAGE_TYPE type, char kind); -extern POOL_PENDING_MESSAGE *pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT *qc); -extern int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE *msg); +extern POOL_PENDING_MESSAGE * pool_pending_message_find_lastest_by_query_context(POOL_QUERY_CONTEXT * qc); +extern int pool_pending_message_get_target_backend_id(POOL_PENDING_MESSAGE * msg); extern void dump_pending_message(void); extern void pool_set_major_version(int major); extern void pool_set_minor_version(int minor); -extern int pool_get_minor_version(void); +extern int pool_get_minor_version(void); #ifdef NOT_USED extern void pool_set_preferred_master_node_id(int node_id); -extern int pool_get_preferred_master_node_id(void); +extern int pool_get_preferred_master_node_id(void); extern void pool_reset_preferred_master_node_id(void); #endif @@ -321,5 +337,5 @@ extern void pool_reset_preferred_master_node_id(void); extern void pool_add_prep_where(char *name, bool *map); extern bool *pool_get_prep_where(char *name); extern void pool_delete_prep_where(char *name); -#endif /* NOT_USED */ -#endif /* POOL_SESSION_CONTEXT_H */ +#endif /* NOT_USED */ +#endif /* POOL_SESSION_CONTEXT_H */ diff --git a/src/include/parser/explain.h b/src/include/parser/explain.h index e7f63e46e..1a44ae216 100644 --- a/src/include/parser/explain.h +++ b/src/include/parser/explain.h @@ -40,15 +40,15 @@ typedef struct ExplainState List *rtable; /* range table */ List *rtable_names; /* alias names for RTEs */ List *deparse_cxt; /* context list for deparsing expressions */ - Bitmapset *printed_subplans; /* ids of SubPlans we've printed */ + Bitmapset *printed_subplans; /* ids of SubPlans we've printed */ } ExplainState; /* Hook for plugins to get control in ExplainOneQuery() */ typedef void (*ExplainOneQuery_hook_type) (Query *query, - IntoClause *into, - ExplainState *es, - const char *queryString, - ParamListInfo params); + IntoClause *into, + ExplainState *es, + const char *queryString, + ParamListInfo params); extern PGDLLIMPORT ExplainOneQuery_hook_type ExplainOneQuery_hook; /* Hook for plugins to get control in explain_get_index_name() */ @@ -95,4 +95,4 @@ extern void ExplainPropertyFloat(const char *qlabel, double value, int ndigits, extern void ExplainPropertyBool(const char *qlabel, bool value, ExplainState *es); -#endif /* EXPLAIN_H */ +#endif /* EXPLAIN_H */ diff --git a/src/include/parser/extensible.h b/src/include/parser/extensible.h index 33c56099f..b11b0a58e 100644 --- a/src/include/parser/extensible.h +++ b/src/include/parser/extensible.h @@ -56,11 +56,11 @@ typedef struct ExtensibleNodeMethods const char *extnodename; Size node_size; void (*nodeCopy) (struct ExtensibleNode *newnode, - const struct ExtensibleNode *oldnode); + const struct ExtensibleNode *oldnode); bool (*nodeEqual) (const struct ExtensibleNode *a, - const struct ExtensibleNode *b); + const struct ExtensibleNode *b); void (*nodeOut) (struct StringInfoData *str, - const struct ExtensibleNode *node); + const struct ExtensibleNode *node); void (*nodeRead) (struct ExtensibleNode *node); } ExtensibleNodeMethods; @@ -75,4 +75,4 @@ extern const ExtensibleNodeMethods *GetExtensibleNodeMethods(const char *name, #define CUSTOMPATH_SUPPORT_BACKWARD_SCAN 0x0001 #define CUSTOMPATH_SUPPORT_MARK_RESTORE 0x0002 -#endif /* EXTENSIBLE_H */ +#endif /* EXTENSIBLE_H */ diff --git a/src/include/parser/gramparse.h b/src/include/parser/gramparse.h index 9ae02321c..adade3693 100644 --- a/src/include/parser/gramparse.h +++ b/src/include/parser/gramparse.h @@ -23,7 +23,7 @@ #include "parsenodes.h" #include "scanner.h" -#define AMTYPE_INDEX 'i' /* index access method */ +#define AMTYPE_INDEX 'i' /* index access method */ /* * NB: include gram.h only AFTER including scanner.h, because scanner.h diff --git a/src/include/parser/lockoptions.h b/src/include/parser/lockoptions.h index 2e55622b0..2bf6b4574 100644 --- a/src/include/parser/lockoptions.h +++ b/src/include/parser/lockoptions.h @@ -43,4 +43,4 @@ typedef enum LockWaitPolicy LockWaitError } LockWaitPolicy; -#endif /* LOCKOPTIONS_H */ +#endif /* LOCKOPTIONS_H */ diff --git a/src/include/parser/makefuncs.h b/src/include/parser/makefuncs.h index 2d7f53a43..9681923bb 100644 --- a/src/include/parser/makefuncs.h +++ b/src/include/parser/makefuncs.h @@ -74,7 +74,7 @@ extern TypeName *makeTypeNameFromNameList(List *names); extern TypeName *makeTypeNameFromOid(Oid typeOid, int32 typmod); extern ColumnDef *makeColumnDef(const char *colname, - Oid typeOid, int32 typmod, Oid collOid); + Oid typeOid, int32 typmod, Oid collOid); extern FuncExpr *makeFuncExpr(Oid funcid, Oid rettype, List *args, Oid funccollid, Oid inputcollid, CoercionForm fformat); diff --git a/src/include/parser/nodes.h b/src/include/parser/nodes.h index a53be5b4d..666df5f83 100644 --- a/src/include/parser/nodes.h +++ b/src/include/parser/nodes.h @@ -498,12 +498,12 @@ typedef enum NodeTag T_TIDBitmap, /* in nodes/tidbitmap.h */ T_InlineCodeBlock, /* in nodes/parsenodes.h */ T_FdwRoutine, /* in foreign/fdwapi.h */ - T_IndexAmRoutine, /* in access/amapi.h */ - TsmRoutine, /* in access/tsmapi.h */ - T_ForeignKeyCacheInfo, /* in utils/rel.h */ + T_IndexAmRoutine, /* in access/amapi.h */ + TsmRoutine , /* in access/tsmapi.h */ + T_ForeignKeyCacheInfo, /* in utils/rel.h */ /* pgpool Extention */ - T_PgpoolVariableSetStmt, - T_PgpoolVariableShowStmt + T_PgpoolVariableSetStmt, + T_PgpoolVariableShowStmt } NodeTag; @@ -743,8 +743,8 @@ typedef enum AggStrategy { AGG_PLAIN, /* simple agg across all input rows */ AGG_SORTED, /* grouped agg, input must be sorted */ - AGG_HASHED, /* grouped agg, use internal hashtable */ - AGG_MIXED /* grouped agg, hash and sort both used */ + AGG_HASHED, /* grouped agg, use internal hashtable */ + AGG_MIXED /* grouped agg, hash and sort both used */ } AggStrategy; /* diff --git a/src/include/parser/parsenodes.h b/src/include/parser/parsenodes.h index ea9964249..e30206f5d 100644 --- a/src/include/parser/parsenodes.h +++ b/src/include/parser/parsenodes.h @@ -123,7 +123,7 @@ typedef struct Query bool hasAggs; /* has aggregates in tlist or havingQual */ bool hasWindowFuncs; /* has window functions in tlist */ - bool hasTargetSRFs; /* has set-returning functions in tlist */ + bool hasTargetSRFs; /* has set-returning functions in tlist */ bool hasSubLinks; /* has subquery SubLink */ bool hasDistinctOn; /* distinctClause is from DISTINCT ON */ bool hasRecursive; /* WITH RECURSIVE was specified */ @@ -255,7 +255,7 @@ typedef enum A_Expr_Kind AEXPR_OP_ANY, /* scalar op ANY (array) */ AEXPR_OP_ALL, /* scalar op ALL (array) */ AEXPR_DISTINCT, /* IS DISTINCT FROM - name must be "=" */ - AEXPR_NOT_DISTINCT, /* IS NOT DISTINCT FROM - name must be "=" */ + AEXPR_NOT_DISTINCT, /* IS NOT DISTINCT FROM - name must be "=" */ AEXPR_NULLIF, /* NULLIF - name must be "=" */ AEXPR_OF, /* IS [NOT] OF - name must be "=" or "<>" */ AEXPR_IN, /* [NOT] IN - name must be "=" or "<>" */ @@ -380,8 +380,8 @@ typedef struct A_Indices { NodeTag type; bool is_slice; /* true if slice (i.e., colon present) */ - Node *lidx; /* slice lower bound, if any */ - Node *uidx; /* subscript, or slice upper bound if any */ + Node *lidx; /* slice lower bound, if any */ + Node *uidx; /* subscript, or slice upper bound if any */ } A_Indices; /* @@ -1844,7 +1844,7 @@ typedef enum GrantObjectType ACL_OBJECT_NAMESPACE, /* namespace */ ACL_OBJECT_TABLESPACE, /* tablespace */ ACL_OBJECT_TYPE /* type */ -} GrantObjectType; +} GrantObjectType; typedef struct GrantStmt { @@ -1932,15 +1932,15 @@ typedef struct AlterDefaultPrivilegesStmt typedef struct CopyStmt { NodeTag type; - RangeVar *relation; /* the relation to copy */ - Node *query; /* the query (SELECT or DML statement with + RangeVar *relation; /* the relation to copy */ + Node *query; /* the query (SELECT or DML statement with * RETURNING) to copy, as a raw parse tree */ - List *attlist; /* List of column names (as Strings), or NIL + List *attlist; /* List of column names (as Strings), or NIL * for all columns */ bool is_from; /* TO or FROM */ bool is_program; /* is 'filename' a program to popen? */ - char *filename; /* filename, or NULL for STDIN/STDOUT */ - List *options; /* List of DefElem nodes */ + char *filename; /* filename, or NULL for STDIN/STDOUT */ + List *options; /* List of DefElem nodes */ } CopyStmt; /* ---------------------- @@ -3088,7 +3088,7 @@ typedef enum VacuumOption VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ VACOPT_NOWAIT = 1 << 5, /* don't wait to get lock (autovacuum only) */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ - VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ + VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ } VacuumOption; typedef struct VacuumStmt diff --git a/src/include/parser/pg_class.h b/src/include/parser/pg_class.h index b745d1639..53103133a 100644 --- a/src/include/parser/pg_class.h +++ b/src/include/parser/pg_class.h @@ -20,7 +20,7 @@ #ifndef PG_CLASS_H #define PG_CLASS_H -#if 0 /* NOT_USED_IN_PGPOOL */ +#if 0 /* NOT_USED_IN_PGPOOL */ #include "catalog/genbki.h" @@ -73,7 +73,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO * not */ bool relispopulated; /* matview currently holds query results */ char relreplident; /* see REPLICA_IDENTITY_xxx constants */ - bool relispartition; /* is relation a partition? */ + bool relispartition; /* is relation a partition? */ TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */ TransactionId relminmxid; /* all multixacts in this rel are >= this. * this is really a MultiXactId */ @@ -121,7 +121,7 @@ typedef FormData_pg_class *Form_pg_class; #define Anum_pg_class_relkind 16 #define Anum_pg_class_relnatts 17 #define Anum_pg_class_relchecks 18 -edefine Anum_pg_class_relhasoids 19 +edefine Anum_pg_class_relhasoids 19 #define Anum_pg_class_relhaspkey 20 #define Anum_pg_class_relhasrules 21 #define Anum_pg_class_relhastriggers 22 @@ -150,33 +150,36 @@ edefine Anum_pg_class_relhasoids 19 * Note: "3" in the relfrozenxid column stands for FirstNormalTransactionId; * similarly, "1" in relminmxid stands for FirstMultiXactId */ -DATA(insert OID = 1247 ( pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f f f t n f 3 1 _null_ _null_ _null_)); + DATA(insert OID = 1247(pg_type PGNSP 71 0 PGUID 0 0 0 0 0 0 0 f f p r 30 0 t f f f f f f t n f 3 1 _null_ _null_ _null_)); + DESCR(""); -DATA(insert OID = 1249 ( pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 22 0 f f f f f f f t n f 3 1 _null_ _null_ _null_)); +DATA(insert OID = 1249(pg_attribute PGNSP 75 0 PGUID 0 0 0 0 0 0 0 f f p r 22 0 f f f f f f f t n f 3 1 _null_ _null_ _null_)); DESCR(""); -DATA(insert OID = 1255 ( pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 29 0 t f f f f f f t n f 3 1 _null_ _null_ _null_)); +DATA(insert OID = 1255(pg_proc PGNSP 81 0 PGUID 0 0 0 0 0 0 0 f f p r 29 0 t f f f f f f t n f 3 1 _null_ _null_ _null_)); DESCR(""); -DATA(insert OID = 1259 ( pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 33 0 t f f f f f f t n f 3 1 _null_ _null_ _null_)); +DATA(insert OID = 1259(pg_class PGNSP 83 0 PGUID 0 0 0 0 0 0 0 f f p r 33 0 t f f f f f f t n f 3 1 _null_ _null_ _null_)); DESCR(""); -#define RELKIND_RELATION 'r' /* ordinary table */ -#define RELKIND_INDEX 'i' /* secondary index */ -#define RELKIND_SEQUENCE 'S' /* sequence object */ -#define RELKIND_TOASTVALUE 't' /* for out-of-line values */ -#define RELKIND_VIEW 'v' /* view */ -#define RELKIND_MATVIEW 'm' /* materialized view */ -#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ -#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ -#define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */ +#define RELKIND_RELATION 'r' /* ordinary table */ +#define RELKIND_INDEX 'i' /* secondary index */ +#define RELKIND_SEQUENCE 'S' /* sequence object */ +#define RELKIND_TOASTVALUE 't' /* for out-of-line + * values */ +#define RELKIND_VIEW 'v' /* view */ +#define RELKIND_MATVIEW 'm' /* materialized view */ +#define RELKIND_COMPOSITE_TYPE 'c' /* composite type */ +#define RELKIND_FOREIGN_TABLE 'f' /* foreign table */ +#define RELKIND_PARTITIONED_TABLE 'p' /* partitioned table */ -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ -#define RELPERSISTENCE_PERMANENT 'p' /* regular table */ -#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent table */ -#define RELPERSISTENCE_TEMP 't' /* temporary table */ +#define RELPERSISTENCE_PERMANENT 'p' /* regular table */ +#define RELPERSISTENCE_UNLOGGED 'u' /* unlogged permanent + * table */ +#define RELPERSISTENCE_TEMP 't' /* temporary table */ -#if 0 /*NOT_USED_IN_PGPOOL*/ +#if 0 /* NOT_USED_IN_PGPOOL */ /* default selection for replica identity (primary key or nothing) */ #define REPLICA_IDENTITY_DEFAULT 'd' @@ -191,9 +194,9 @@ DESCR(""); */ #define REPLICA_IDENTITY_INDEX 'i' -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ -#endif /* PG_CLASS_H */ +#endif /* PG_CLASS_H */ diff --git a/src/include/parser/pool_parser.h b/src/include/parser/pool_parser.h index a25e2ccf6..0e90f7c19 100644 --- a/src/include/parser/pool_parser.h +++ b/src/include/parser/pool_parser.h @@ -170,17 +170,16 @@ typedef int16 AttrNumber; /* NoLock is not a lock mode, but a flag value meaning "don't get a lock" */ #define NoLock 0 -#define AccessShareLock 1 /* SELECT */ -#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */ -#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */ -#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL) */ -#define ShareLock 5 /* CREATE INDEX */ -#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW - * SHARE */ -#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR - * UPDATE */ -#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM - * FULL, and unqualified LOCK TABLE */ +#define AccessShareLock 1 /* SELECT */ +#define RowShareLock 2 /* SELECT FOR UPDATE/FOR SHARE */ +#define RowExclusiveLock 3 /* INSERT, UPDATE, DELETE */ +#define ShareUpdateExclusiveLock 4 /* VACUUM (non-FULL) */ +#define ShareLock 5 /* CREATE INDEX */ +#define ShareRowExclusiveLock 6 /* like EXCLUSIVE MODE, but allows ROW + * SHARE */ +#define ExclusiveLock 7 /* blocks ROW SHARE/SELECT...FOR UPDATE */ +#define AccessExclusiveLock 8 /* ALTER TABLE, DROP TABLE, VACUUM FULL, + * and unqualified LOCK TABLE */ #define DEFAULT_INDEX_TYPE "btree" #define NUMERIC_MAX_PRECISION 1000 @@ -191,4 +190,4 @@ typedef int16 AttrNumber; -#endif /* POOL_PARSER_H */ +#endif /* POOL_PARSER_H */ diff --git a/src/include/parser/pool_string.h b/src/include/parser/pool_string.h index 886cb320b..d943cdf05 100644 --- a/src/include/parser/pool_string.h +++ b/src/include/parser/pool_string.h @@ -23,16 +23,16 @@ typedef struct { - int size; - int len; - char *data; -} String; + int size; + int len; + char *data; +} String; extern char *NameListToString(List *names); -extern String *init_string(char *str); -extern void string_append_string(String *string, String *append_data); -extern void string_append_char(String *string, char *append_data); -extern void free_string(String *string); -extern String *copy_string(String *string); +extern String * init_string(char *str); +extern void string_append_string(String * string, String * append_data); +extern void string_append_char(String * string, char *append_data); +extern void free_string(String * string); +extern String * copy_string(String * string); -#endif /* POOL_STRING_H */ +#endif /* POOL_STRING_H */ diff --git a/src/include/parser/primnodes.h b/src/include/parser/primnodes.h index a2138dee8..cedd67bc1 100644 --- a/src/include/parser/primnodes.h +++ b/src/include/parser/primnodes.h @@ -37,6 +37,7 @@ typedef struct Bitmapset } Bitmapset; /* VARIABLE LENGTH STRUCT */ extern Bitmapset *bms_copy(const Bitmapset *a); + /* include/nodes/bitmapset.h end */ /* @@ -308,12 +309,12 @@ typedef struct Aggref Oid aggcollid; /* OID of collation of result */ Oid inputcollid; /* OID of collation that function should use */ Oid aggtranstype; /* type Oid of aggregate's transition value */ - List *aggargtypes; /* type Oids of direct and aggregated args */ - List *aggdirectargs; /* direct arguments, if an ordered-set agg */ - List *args; /* aggregated arguments and sort expressions */ - List *aggorder; /* ORDER BY (list of SortGroupClause) */ - List *aggdistinct; /* DISTINCT (list of SortGroupClause) */ - Expr *aggfilter; /* FILTER expression, if any */ + List *aggargtypes; /* type Oids of direct and aggregated args */ + List *aggdirectargs; /* direct arguments, if an ordered-set agg */ + List *args; /* aggregated arguments and sort expressions */ + List *aggorder; /* ORDER BY (list of SortGroupClause) */ + List *aggdistinct; /* DISTINCT (list of SortGroupClause) */ + Expr *aggfilter; /* FILTER expression, if any */ bool aggstar; /* TRUE if argument list was really '*' */ bool aggvariadic; /* true if variadic arguments have been * combined into an array last argument */ @@ -1189,9 +1190,9 @@ typedef enum NullTestType typedef struct NullTest { Expr xpr; - Expr *arg; /* input expression */ + Expr *arg; /* input expression */ NullTestType nulltesttype; /* IS NULL, IS NOT NULL */ - bool argisrow; /* T to perform field-by-field null checks */ + bool argisrow; /* T to perform field-by-field null checks */ int location; /* token location, or -1 if unknown */ } NullTest; diff --git a/src/include/parser/scansup.h b/src/include/parser/scansup.h index 40f3d9c49..93179d3b7 100644 --- a/src/include/parser/scansup.h +++ b/src/include/parser/scansup.h @@ -28,4 +28,4 @@ extern void truncate_identifier(char *ident, int len, bool warn); extern bool scanner_isspace(char ch); -#endif /* SCANSUP_H */ +#endif /* SCANSUP_H */ diff --git a/src/include/parser/stringinfo.h b/src/include/parser/stringinfo.h index f678b1ee2..a704293b9 100644 --- a/src/include/parser/stringinfo.h +++ b/src/include/parser/stringinfo.h @@ -26,7 +26,7 @@ /* port.h */ #ifdef USE_REPL_SNPRINTF -extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); +extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); /* * The GCC-specific code below prevents the __attribute__(... 'printf') @@ -42,7 +42,7 @@ extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); #endif #endif -#endif /* USE_REPL_SNPRINTF */ +#endif /* USE_REPL_SNPRINTF */ /* utils.memutils.h */ @@ -63,7 +63,7 @@ extern int pg_vsnprintf(char *str, size_t count, const char *fmt, va_list args); * MemoryContextAllocHuge(). Both limits permit code to assume that it may * compute twice an allocation's size without overflow. */ -#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ +#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ /*------------------------- diff --git a/src/include/pcp/libpcp_ext.h b/src/include/pcp/libpcp_ext.h index 2fdd6ba3e..ae5ac8a9d 100644 --- a/src/include/pcp/libpcp_ext.h +++ b/src/include/pcp/libpcp_ext.h @@ -1,7 +1,7 @@ /* * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -18,7 +18,7 @@ * is" without express or implied warranty. * * - * libpcp_ext.h - + * libpcp_ext.h - * This file contains definitions for structures and * externs for functions used by frontend libpcp applications. */ @@ -43,12 +43,13 @@ #define MAX_DB_HOST_NAMELEN 128 #define MAX_PATH_LENGTH 256 -typedef enum { - CON_UNUSED, /* unused slot */ - CON_CONNECT_WAIT, /* waiting for connection starting */ - CON_UP, /* up and running */ - CON_DOWN /* down, disconnected */ -} BACKEND_STATUS; +typedef enum +{ + CON_UNUSED, /* unused slot */ + CON_CONNECT_WAIT, /* waiting for connection starting */ + CON_UP, /* up and running */ + CON_DOWN /* down, disconnected */ +} BACKEND_STATUS; /* backend status name strings */ #define BACKEND_STATUS_CON_UNUSED "unused" @@ -60,93 +61,97 @@ typedef enum { /* * Backend status record file */ -typedef struct { +typedef struct +{ BACKEND_STATUS status[MAX_NUM_BACKENDS]; -} BackendStatusRecord; +} BackendStatusRecord; -typedef enum { +typedef enum +{ ROLE_MASTER, ROLE_SLAVE, ROLE_PRIMARY, ROLE_STANDBY -} SERVER_ROLE; +} SERVER_ROLE; /* * PostgreSQL backend descriptor. Placed on shared memory area. */ -typedef struct { - char backend_hostname[MAX_DB_HOST_NAMELEN]; /* backend host name */ - int backend_port; /* backend port numbers */ +typedef struct +{ + char backend_hostname[MAX_DB_HOST_NAMELEN]; /* backend host name */ + int backend_port; /* backend port numbers */ BACKEND_STATUS backend_status; /* backend status */ - time_t status_changed_time; /* backend status changed time */ - double backend_weight; /* normalized backend load balance ratio */ - double unnormalized_weight; /* descripted parameter */ - char backend_data_directory[MAX_PATH_LENGTH]; + time_t status_changed_time; /* backend status changed time */ + double backend_weight; /* normalized backend load balance ratio */ + double unnormalized_weight; /* descripted parameter */ + char backend_data_directory[MAX_PATH_LENGTH]; unsigned short flag; /* various flags */ - bool quarantine; /* true if node is CON_DOWN because of quarantine */ - uint64 standby_delay; /* The replication delay against the primary */ - SERVER_ROLE role; /* Role of server. used by pcp_node_info and failover() - * to keep track of quarantined primary node - */ -} BackendInfo; - -typedef struct { - sig_atomic_t num_backends; /* Number of used PostgreSQL backends. - * This needs to be a sig_atomic_t type - * since it is replaced by a local - * variable while reloading pgpool.conf. - */ + bool quarantine; /* true if node is CON_DOWN because of + * quarantine */ + uint64 standby_delay; /* The replication delay against the primary */ + SERVER_ROLE role; /* Role of server. used by pcp_node_info and + * failover() to keep track of quarantined + * primary node */ +} BackendInfo; + +typedef struct +{ + sig_atomic_t num_backends; /* Number of used PostgreSQL backends. This + * needs to be a sig_atomic_t type since it is + * replaced by a local variable while + * reloading pgpool.conf. */ BackendInfo backend_info[MAX_NUM_BACKENDS]; -} BackendDesc; +} BackendDesc; + /* * Connection pool information. Placed on shared memory area. */ -typedef struct { - int backend_id; /* backend id */ +typedef struct +{ + int backend_id; /* backend id */ char database[SM_DATABASE]; /* Database name */ char user[SM_USER]; /* User name */ - int major; /* protocol major version */ - int minor; /* protocol minor version */ - int pid; /* backend process id */ - int key; /* cancel key */ - int counter; /* used counter */ - time_t create_time; /* connection creation time */ - int load_balancing_node; /* load balancing node */ - char connected; /* True if frontend connected. Please note - * that we use "char" instead of "bool". - * Since 3.1, we need to export this - * structure so that PostgreSQL C - * functions can use. Problem is, - * PostgreSQL defines bool itself, and if - * we use bool, the size of the structure - * might be out of control of - * pgpool-II. So we use "char" here. - */ - volatile char swallow_termination; - /* Flag to mark that if the connection will - * be terminated by the backend. it should - * not be treated as a backend node failure. - * This flag is used to handle - * pg_terminate_backend() - */ -} ConnectionInfo; + int major; /* protocol major version */ + int minor; /* protocol minor version */ + int pid; /* backend process id */ + int key; /* cancel key */ + int counter; /* used counter */ + time_t create_time; /* connection creation time */ + int load_balancing_node; /* load balancing node */ + char connected; /* True if frontend connected. Please note + * that we use "char" instead of "bool". Since + * 3.1, we need to export this structure so + * that PostgreSQL C functions can use. + * Problem is, PostgreSQL defines bool itself, + * and if we use bool, the size of the + * structure might be out of control of + * pgpool-II. So we use "char" here. */ + volatile char swallow_termination; + + /* + * Flag to mark that if the connection will be terminated by the backend. + * it should not be treated as a backend node failure. This flag is used + * to handle pg_terminate_backend() + */ +} ConnectionInfo; /* * process information * This object put on shared memory. */ -typedef struct { - pid_t pid; /* OS's process id */ - time_t start_time; /* fork() time */ - ConnectionInfo *connection_info; /* head of the connection info for this process */ - char need_to_restart; /* If non 0, exit this child process - * as soon as current session ends. - * Typical case this flag being set is - * failback a node in streaming - * replication mode. - */ -} ProcessInfo; +typedef struct +{ + pid_t pid; /* OS's process id */ + time_t start_time; /* fork() time */ + ConnectionInfo *connection_info; /* head of the connection info for + * this process */ + char need_to_restart; /* If non 0, exit this child process as + * soon as current session ends. Typical + * case this flag being set is failback a + * node in streaming replication mode. */ +} ProcessInfo; /* * reporting types @@ -164,140 +169,153 @@ typedef struct { #define POOLCONFIG_MAXCOUNTLEN 16 /* config report struct*/ -typedef struct { - char name[POOLCONFIG_MAXNAMELEN+1]; - char value[POOLCONFIG_MAXVALLEN+1]; - char desc[POOLCONFIG_MAXDESCLEN+1]; -} POOL_REPORT_CONFIG; +typedef struct +{ + char name[POOLCONFIG_MAXNAMELEN + 1]; + char value[POOLCONFIG_MAXVALLEN + 1]; + char desc[POOLCONFIG_MAXDESCLEN + 1]; +} POOL_REPORT_CONFIG; /* nodes report struct */ -typedef struct { - char node_id[POOLCONFIG_MAXIDLEN+1]; - char hostname[MAX_DB_HOST_NAMELEN+1]; - char port[POOLCONFIG_MAXPORTLEN+1]; - char status[POOLCONFIG_MAXSTATLEN+1]; - char lb_weight[POOLCONFIG_MAXWEIGHTLEN+1]; - char role[POOLCONFIG_MAXWEIGHTLEN+1]; - char select[POOLCONFIG_MAXWEIGHTLEN+1]; - char load_balance_node[POOLCONFIG_MAXWEIGHTLEN+1]; - char delay[POOLCONFIG_MAXWEIGHTLEN+1]; - char last_status_change[POOLCONFIG_MAXDATELEN]; -} POOL_REPORT_NODES; +typedef struct +{ + char node_id[POOLCONFIG_MAXIDLEN + 1]; + char hostname[MAX_DB_HOST_NAMELEN + 1]; + char port[POOLCONFIG_MAXPORTLEN + 1]; + char status[POOLCONFIG_MAXSTATLEN + 1]; + char lb_weight[POOLCONFIG_MAXWEIGHTLEN + 1]; + char role[POOLCONFIG_MAXWEIGHTLEN + 1]; + char select[POOLCONFIG_MAXWEIGHTLEN + 1]; + char load_balance_node[POOLCONFIG_MAXWEIGHTLEN + 1]; + char delay[POOLCONFIG_MAXWEIGHTLEN + 1]; + char last_status_change[POOLCONFIG_MAXDATELEN]; +} POOL_REPORT_NODES; /* processes report struct */ -typedef struct { - char pool_pid[POOLCONFIG_MAXCOUNTLEN+1]; - char start_time[POOLCONFIG_MAXDATELEN+1]; - char database[POOLCONFIG_MAXIDENTLEN+1]; - char username[POOLCONFIG_MAXIDENTLEN+1]; - char create_time[POOLCONFIG_MAXDATELEN+1]; - char pool_counter[POOLCONFIG_MAXCOUNTLEN+1]; -} POOL_REPORT_PROCESSES; +typedef struct +{ + char pool_pid[POOLCONFIG_MAXCOUNTLEN + 1]; + char start_time[POOLCONFIG_MAXDATELEN + 1]; + char database[POOLCONFIG_MAXIDENTLEN + 1]; + char username[POOLCONFIG_MAXIDENTLEN + 1]; + char create_time[POOLCONFIG_MAXDATELEN + 1]; + char pool_counter[POOLCONFIG_MAXCOUNTLEN + 1]; +} POOL_REPORT_PROCESSES; /* pools reporting struct */ -typedef struct { - int pool_pid; - time_t start_time; - int pool_id; - int backend_id; - char database[POOLCONFIG_MAXIDENTLEN+1]; - char username[POOLCONFIG_MAXIDENTLEN+1]; - time_t create_time; - int pool_majorversion; - int pool_minorversion; - int pool_counter; - int pool_backendpid; - int pool_connected; -} POOL_REPORT_POOLS; +typedef struct +{ + int pool_pid; + time_t start_time; + int pool_id; + int backend_id; + char database[POOLCONFIG_MAXIDENTLEN + 1]; + char username[POOLCONFIG_MAXIDENTLEN + 1]; + time_t create_time; + int pool_majorversion; + int pool_minorversion; + int pool_counter; + int pool_backendpid; + int pool_connected; +} POOL_REPORT_POOLS; /* version struct */ -typedef struct { - char version[POOLCONFIG_MAXVALLEN+1]; -} POOL_REPORT_VERSION; +typedef struct +{ + char version[POOLCONFIG_MAXVALLEN + 1]; +} POOL_REPORT_VERSION; -typedef enum { +typedef enum +{ PCP_CONNECTION_OK, PCP_CONNECTION_CONNECTED, PCP_CONNECTION_NOT_CONNECTED, PCP_CONNECTION_BAD, PCP_CONNECTION_AUTH_ERROR -}ConnStateType; +} ConnStateType; -typedef enum { +typedef enum +{ PCP_RES_COMMAND_OK, PCP_RES_BAD_RESPONSE, PCP_RES_BACKEND_ERROR, PCP_RES_INCOMPLETE, PCP_RES_ERROR -}ResultStateType; +} ResultStateType; struct PCPConnInfo; -typedef struct { - int isint; /* 1 if data in slot is integer, 0 otherwise */ - int datalen; /* Length of binary data*/ +typedef struct +{ + int isint; /* 1 if data in slot is integer, 0 otherwise */ + int datalen; /* Length of binary data */ union { - int* ptr; - int integer; - }data; - void (*free_func)(struct PCPConnInfo*,void*); /* custom free function deep free of data */ -}PCPResultSlot; - -typedef struct { + int *ptr; + int integer; + } data; + void (*free_func) (struct PCPConnInfo *, void *); /* custom free function + * deep free of data */ +} PCPResultSlot; + +typedef struct +{ ResultStateType resultStatus; - int resultSlots; /* Total number of slots contained in this result */ - int nextFillSlot; /* internal to keep track of last filled slot */ - PCPResultSlot resultSlot[1]; /* variable length slots */ -}PCPResultInfo; - -typedef struct PCPConnInfo{ - void *pcpConn; - char *errMsg; /* error message, or NULL if no error */ - ConnStateType connState; - PCPResultInfo *pcpResInfo; - FILE *Pfdebug; /* File pointer to output debug infor */ -}PCPConnInfo; + int resultSlots; /* Total number of slots contained in this + * result */ + int nextFillSlot; /* internal to keep track of last filled slot */ + PCPResultSlot resultSlot[1]; /* variable length slots */ +} PCPResultInfo; + +typedef struct PCPConnInfo +{ + void *pcpConn; + char *errMsg; /* error message, or NULL if no error */ + ConnStateType connState; + PCPResultInfo *pcpResInfo; + FILE *Pfdebug; /* File pointer to output debug infor */ +} PCPConnInfo; struct WdInfo; -extern PCPConnInfo* pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug); -extern void pcp_disconnect(PCPConnInfo* pcpConn); +extern PCPConnInfo * pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug); +extern void pcp_disconnect(PCPConnInfo * pcpConn); -extern PCPResultInfo *pcp_terminate_pgpool(PCPConnInfo* pcpCon,char mode); -extern PCPResultInfo *pcp_node_count(PCPConnInfo* pcpCon); -extern PCPResultInfo *pcp_node_info(PCPConnInfo* pcpCon, int nid); +extern PCPResultInfo * pcp_terminate_pgpool(PCPConnInfo * pcpCon, char mode); +extern PCPResultInfo * pcp_node_count(PCPConnInfo * pcpCon); +extern PCPResultInfo * pcp_node_info(PCPConnInfo * pcpCon, int nid); -extern PCPResultInfo *pcp_process_count(PCPConnInfo* pcpConn); -extern PCPResultInfo *pcp_process_info(PCPConnInfo* pcpConn, int pid); +extern PCPResultInfo * pcp_process_count(PCPConnInfo * pcpConn); +extern PCPResultInfo * pcp_process_info(PCPConnInfo * pcpConn, int pid); -extern PCPResultInfo *pcp_detach_node(PCPConnInfo* pcpConn,int nid); -extern PCPResultInfo *pcp_detach_node_gracefully(PCPConnInfo* pcpConn,int nid); -extern PCPResultInfo *pcp_attach_node(PCPConnInfo* pcpConn, int nid); -extern PCPResultInfo *pcp_pool_status(PCPConnInfo *pcpConn); -extern PCPResultInfo *pcp_recovery_node(PCPConnInfo* pcpConn, int nid); -extern PCPResultInfo *pcp_promote_node(PCPConnInfo* pcpConn, int nid); -extern PCPResultInfo *pcp_promote_node_gracefully(PCPConnInfo* pcpConn,int nid); -extern PCPResultInfo *pcp_watchdog_info(PCPConnInfo* pcpConn, int nid); -extern PCPResultInfo *pcp_set_backend_parameter(PCPConnInfo* pcpConn,char* parameter_name, char* value); +extern PCPResultInfo * pcp_detach_node(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_detach_node_gracefully(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_attach_node(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_pool_status(PCPConnInfo * pcpConn); +extern PCPResultInfo * pcp_recovery_node(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_promote_node(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_promote_node_gracefully(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_watchdog_info(PCPConnInfo * pcpConn, int nid); +extern PCPResultInfo * pcp_set_backend_parameter(PCPConnInfo * pcpConn, char *parameter_name, char *value); -extern ResultStateType PCPResultStatus(const PCPResultInfo *res); -extern ConnStateType PCPConnectionStatus(const PCPConnInfo *conn); -extern void* pcp_get_binary_data(const PCPResultInfo *res, unsigned int slotno); -extern int pcp_get_int_data(const PCPResultInfo *res, unsigned int slotno); -extern int pcp_get_data_length(const PCPResultInfo *res, unsigned int slotno); -extern void pcp_free_result(PCPConnInfo* pcpConn); -extern void pcp_free_connection(PCPConnInfo* pcpConn); -extern int pcp_result_slot_count(PCPResultInfo* res); -extern char *pcp_get_last_error(PCPConnInfo* pcpConn); +extern ResultStateType PCPResultStatus(const PCPResultInfo * res); +extern ConnStateType PCPConnectionStatus(const PCPConnInfo * conn); +extern void *pcp_get_binary_data(const PCPResultInfo * res, unsigned int slotno); +extern int pcp_get_int_data(const PCPResultInfo * res, unsigned int slotno); +extern int pcp_get_data_length(const PCPResultInfo * res, unsigned int slotno); +extern void pcp_free_result(PCPConnInfo * pcpConn); +extern void pcp_free_connection(PCPConnInfo * pcpConn); +extern int pcp_result_slot_count(PCPResultInfo * res); +extern char *pcp_get_last_error(PCPConnInfo * pcpConn); -extern int pcp_result_is_empty(PCPResultInfo* res); +extern int pcp_result_is_empty(PCPResultInfo * res); extern char *role_to_str(SERVER_ROLE role); + /* ------------------------------ * pcp_error.c * ------------------------------ */ -#endif /* LIBPCP_EXT_H */ +#endif /* LIBPCP_EXT_H */ diff --git a/src/include/pcp/pcp.h b/src/include/pcp/pcp.h index d05c340a2..68d2586fd 100644 --- a/src/include/pcp/pcp.h +++ b/src/include/pcp/pcp.h @@ -1,7 +1,7 @@ /* * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2016 PgPool Global Development Group @@ -37,28 +37,28 @@ typedef struct PCPWDNodeInfo { - int state; - char nodeName[WD_MAX_HOST_NAMELEN]; - char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ - char stateName[WD_MAX_HOST_NAMELEN]; /* state name */ - int wd_port; /* watchdog port */ - int wd_priority; /* node priority in leader election */ - int pgpool_port; /* pgpool port */ - char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ - int id; -}PCPWDNodeInfo; + int state; + char nodeName[WD_MAX_HOST_NAMELEN]; + char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ + char stateName[WD_MAX_HOST_NAMELEN]; /* state name */ + int wd_port; /* watchdog port */ + int wd_priority; /* node priority in leader election */ + int pgpool_port; /* pgpool port */ + char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ + int id; +} PCPWDNodeInfo; typedef struct PCPWDClusterInfo { - int remoteNodeCount; - int quorumStatus; - int aliveNodeCount; - bool escalated; - char masterNodeName[WD_MAX_HOST_NAMELEN]; - char masterHostName[WD_MAX_HOST_NAMELEN]; - int nodeCount; + int remoteNodeCount; + int quorumStatus; + int aliveNodeCount; + bool escalated; + char masterNodeName[WD_MAX_HOST_NAMELEN]; + char masterHostName[WD_MAX_HOST_NAMELEN]; + int nodeCount; PCPWDNodeInfo nodeList[1]; -}PCPWDClusterInfo; +} PCPWDClusterInfo; /* -------------------------------- * pcp.c @@ -70,4 +70,4 @@ typedef struct PCPWDClusterInfo * ------------------------------ */ -#endif /* PCP_H */ +#endif /* PCP_H */ diff --git a/src/include/pcp/pcp_stream.h b/src/include/pcp/pcp_stream.h index 254b98cb2..b1f9efb59 100644 --- a/src/include/pcp/pcp_stream.h +++ b/src/include/pcp/pcp_stream.h @@ -1,7 +1,7 @@ /* * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2008 PgPool Global Development Group @@ -29,25 +29,26 @@ #define WRITEBUFSZ 8192 -typedef struct { - int fd; /* fd for connection */ +typedef struct +{ + int fd; /* fd for connection */ - char *wbuf; /* write buffer for the connection */ - int wbufsz; /* write buffer size */ - int wbufpo; /* buffer offset */ + char *wbuf; /* write buffer for the connection */ + int wbufsz; /* write buffer size */ + int wbufpo; /* buffer offset */ - char *hp; /* pending data buffer head address */ - int po; /* pending data offset */ - int bufsz; /* pending data buffer size */ - int len; /* pending data length */ -} PCP_CONNECTION; + char *hp; /* pending data buffer head address */ + int po; /* pending data offset */ + int bufsz; /* pending data buffer size */ + int len; /* pending data length */ +} PCP_CONNECTION; -extern PCP_CONNECTION *pcp_open(int fd); -extern void pcp_close(PCP_CONNECTION *pc); -extern int pcp_read(PCP_CONNECTION *pc, void *buf, int len); -extern int pcp_write(PCP_CONNECTION *pc, void *buf, int len); -extern int pcp_flush(PCP_CONNECTION *pc); +extern PCP_CONNECTION * pcp_open(int fd); +extern void pcp_close(PCP_CONNECTION * pc); +extern int pcp_read(PCP_CONNECTION * pc, void *buf, int len); +extern int pcp_write(PCP_CONNECTION * pc, void *buf, int len); +extern int pcp_flush(PCP_CONNECTION * pc); #define UNIX_DOMAIN_PATH "/tmp" -#endif /* PCP_STREAM_H */ +#endif /* PCP_STREAM_H */ diff --git a/src/include/pool.h b/src/include/pool.h index 4705d1823..c27a375d6 100644 --- a/src/include/pool.h +++ b/src/include/pool.h @@ -1,7 +1,7 @@ /* -*-pgsql-c-*- */ /* * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -97,21 +97,23 @@ #define OPERATION_TIMEOUT (-3) -typedef enum { +typedef enum +{ POOL_CONTINUE = 0, POOL_IDLE, POOL_END, POOL_ERROR, POOL_FATAL, POOL_DEADLOCK -} POOL_STATUS; +} POOL_STATUS; -typedef enum { +typedef enum +{ POOL_SOCKET_CLOSED = 0, POOL_SOCKET_VALID, POOL_SOCKET_ERROR, POOL_SOCKET_EOF -} POOL_SOCKET_STATE; +} POOL_SOCKET_STATE; /* protocol major version numbers */ #define PROTO_MAJOR_V2 2 @@ -131,40 +133,44 @@ typedef enum { typedef struct StartupPacket_v2 { - int protoVersion; /* Protocol version */ + int protoVersion; /* Protocol version */ char database[SM_DATABASE]; /* Database name */ char user[SM_USER]; /* User name */ char options[SM_OPTIONS]; /* Optional additional args */ - char unused[SM_UNUSED]; /* Unused */ + char unused[SM_UNUSED]; /* Unused */ char tty[SM_TTY]; /* Tty for debug output */ -} StartupPacket_v2; +} StartupPacket_v2; /* startup packet info */ typedef struct { - char *startup_packet; /* raw startup packet without packet length (malloced area) */ - int len; /* raw startup packet length */ - int major; /* protocol major version */ - int minor; /* protocol minor version */ - char *database; /* database name in startup_packet (malloced area) */ - char *user; /* user name in startup_packet (malloced area) */ - char *application_name; /* not malloced. pointing to in startup_packet */ + char *startup_packet; /* raw startup packet without packet length + * (malloced area) */ + int len; /* raw startup packet length */ + int major; /* protocol major version */ + int minor; /* protocol minor version */ + char *database; /* database name in startup_packet (malloced + * area) */ + char *user; /* user name in startup_packet (malloced area) */ + char *application_name; /* not malloced. pointing to in + * startup_packet */ } StartupPacket; typedef struct CancelPacket { - int protoVersion; /* Protocol version */ - int pid; /* backend process id */ - int key; /* cancel key */ -} CancelPacket; + int protoVersion; /* Protocol version */ + int pid; /* backend process id */ + int key; /* cancel key */ +} CancelPacket; #define MAX_PASSWORD_SIZE 1024 -typedef struct { - int num; /* number of entries */ - char **names; /* parameter names */ - char **values; /* values */ -} ParamStatus; +typedef struct +{ + int num; /* number of entries */ + char **names; /* parameter names */ + char **values; /* values */ +} ParamStatus; /* * HbaLines is declared in pool_hba.h @@ -175,60 +181,62 @@ typedef struct HbaLine HbaLine; /* * stream connection structure */ -typedef struct { - int fd; /* fd for connection */ +typedef struct +{ + int fd; /* fd for connection */ - char *wbuf; /* write buffer for the connection */ - int wbufsz; /* write buffer size */ - int wbufpo; /* buffer offset */ + char *wbuf; /* write buffer for the connection */ + int wbufsz; /* write buffer size */ + int wbufpo; /* buffer offset */ #ifdef USE_SSL - SSL_CTX *ssl_ctx; /* SSL connection context */ - SSL *ssl; /* SSL connection */ - X509 *peer; - char *cert_cn; /* common in the ssl certificate - * presented by frontend connection - * Used for cert authentication - */ - bool client_cert_loaded; + SSL_CTX *ssl_ctx; /* SSL connection context */ + SSL *ssl; /* SSL connection */ + X509 *peer; + char *cert_cn; /* common in the ssl certificate presented by + * frontend connection Used for cert + * authentication */ + bool client_cert_loaded; #endif - int ssl_active; /* SSL is failed if < 0, off if 0, on if > 0 */ + int ssl_active; /* SSL is failed if < 0, off if 0, on if > 0 */ - char *hp; /* pending data buffer head address */ - int po; /* pending data offset */ - int bufsz; /* pending data buffer size */ - int len; /* pending data length */ + char *hp; /* pending data buffer head address */ + int po; /* pending data offset */ + int bufsz; /* pending data buffer size */ + int len; /* pending data length */ - char *sbuf; /* buffer for pool_read_string */ - int sbufsz; /* its size in bytes */ + char *sbuf; /* buffer for pool_read_string */ + int sbufsz; /* its size in bytes */ - char *buf2; /* buffer for pool_read2 */ - int bufsz2; /* its size in bytes */ + char *buf2; /* buffer for pool_read2 */ + int bufsz2; /* its size in bytes */ - char *buf3; /* buffer for pool_push/pop */ - int bufsz3; /* its size in bytes */ + char *buf3; /* buffer for pool_push/pop */ + int bufsz3; /* its size in bytes */ - int isbackend; /* this connection is for backend if non 0 */ - int db_node_id; /* DB node id for this connection */ + int isbackend; /* this connection is for backend if non 0 */ + int db_node_id; /* DB node id for this connection */ - char tstate; /* Transaction state (V3 only) 'I' if idle - * (not in a transaction block); 'T' if in a - * transaction block; or 'E' if in a failed - * transaction block - */ + char tstate; /* Transaction state (V3 only) 'I' if idle + * (not in a transaction block); 'T' if in a + * transaction block; or 'E' if in a failed + * transaction block */ /* True if an internal transaction has already started */ - bool is_internal_transaction_started; + bool is_internal_transaction_started; /* * following are used to remember when re-use the authenticated connection */ - int auth_kind; /* 3: clear text password, 4: crypt password, 5: md5 password */ - int pwd_size; /* password (sent back from frontend) size in host order */ - char password[MAX_PASSWORD_SIZE +1 ]; /* password (sent back from frontend) */ - char salt[4]; /* password salt */ - PasswordType passwordType; + int auth_kind; /* 3: clear text password, 4: crypt password, + * 5: md5 password */ + int pwd_size; /* password (sent back from frontend) size in + * host order */ + char password[MAX_PASSWORD_SIZE + 1]; /* password (sent back + * from frontend) */ + char salt[4]; /* password salt */ + PasswordType passwordType; /* * following are used to remember current session parameter status. @@ -236,53 +244,56 @@ typedef struct { */ ParamStatus params; - int no_forward; /* if non 0, do not write to frontend */ + int no_forward; /* if non 0, do not write to frontend */ - char kind; /* kind cache */ + char kind; /* kind cache */ /* true if remote end closed the connection */ POOL_SOCKET_STATE socket_state; + /* * frontend info needed for hba */ - int protoVersion; - SockAddr raddr; - HbaLine *pool_hba; - char *database; - char *username; - char *remote_hostname; - int remote_hostname_resolv; - bool frontend_authenticated; + int protoVersion; + SockAddr raddr; + HbaLine *pool_hba; + char *database; + char *username; + char *remote_hostname; + int remote_hostname_resolv; + bool frontend_authenticated; PasswordMapping *passwordMapping; - ConnectionInfo *con_info; /* shared memory coninfo used - * for handling the query containing - * pg_terminate_backend*/ -} POOL_CONNECTION; + ConnectionInfo *con_info; /* shared memory coninfo used for handling the + * query containing pg_terminate_backend */ +} POOL_CONNECTION; /* * connection pool structure */ -typedef struct { - StartupPacket *sp; /* startup packet info */ - int pid; /* backend pid */ - int key; /* cancel key */ - POOL_CONNECTION *con; - time_t closetime; /* absolute time in second when the connection closed - * if 0, that means the connection is under use. - */ -} POOL_CONNECTION_POOL_SLOT; - -typedef struct { +typedef struct +{ + StartupPacket *sp; /* startup packet info */ + int pid; /* backend pid */ + int key; /* cancel key */ + POOL_CONNECTION *con; + time_t closetime; /* absolute time in second when the connection + * closed if 0, that means the connection is + * under use. */ +} POOL_CONNECTION_POOL_SLOT; + +typedef struct +{ ConnectionInfo *info; /* connection info on shmem */ - POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; -} POOL_CONNECTION_POOL; + POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; +} POOL_CONNECTION_POOL; -/* - * for pool_clear_cache() in pool_query_cache.c +/* + * for pool_clear_cache() in pool_query_cache.c * * used to specify the time which cached data created before it to be deleted. */ -typedef enum { +typedef enum +{ second, seconds, minute, minutes, hour, hours, @@ -293,15 +304,16 @@ typedef enum { decade, decades, century, centuries, millennium, millenniums -} UNIT; +} UNIT; -typedef struct { - int quantity; - UNIT unit; +typedef struct +{ + int quantity; + UNIT unit; } Interval; /* Defined in pool_session_context.h */ -extern int pool_get_major_version(void); +extern int pool_get_major_version(void); /* NUM_BACKENDS now always returns actual number of backends */ #define NUM_BACKENDS (pool_config->backend_desc->num_backends) @@ -314,9 +326,9 @@ extern int pool_get_major_version(void); * no query is in progress and the DB node is healthy */ extern bool pool_is_node_to_be_sent_in_current_query(int node_id); -extern int pool_virtual_master_db_node_id(void); -extern BACKEND_STATUS* my_backend_status[]; -extern int my_master_node_id; +extern int pool_virtual_master_db_node_id(void); +extern BACKEND_STATUS * my_backend_status[]; +extern int my_master_node_id; #define VALID_BACKEND(backend_id) \ ((RAW_MODE && (backend_id) == REAL_MASTER_NODE_ID) || \ @@ -368,12 +380,13 @@ extern int my_master_node_id; /* * Backend node status in streaming replication mode. */ -typedef enum { +typedef enum +{ POOL_NODE_STATUS_UNUSED, /* unused */ POOL_NODE_STATUS_PRIMARY, /* primary ndoe */ POOL_NODE_STATUS_STANDBY, /* standby node */ POOL_NODE_STATUS_INVALID /* invalid node (split branin, stand alone) */ -} POOL_NODE_STATUS; +} POOL_NODE_STATUS; #define REPLICATION (pool_config->replication_mode) #define MASTER_SLAVE (pool_config->master_slave_mode) @@ -382,7 +395,7 @@ typedef enum { #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 SL_MODE (STREAM || LOGICAL) /* streaming or logical replication mode */ +#define SL_MODE (STREAM || LOGICAL) /* streaming or logical replication mode */ #define MAJOR(p) (pool_get_major_version()) #define TSTATE(p, i) (CONNECTION(p, i)->tstate) #define INTERNAL_TRANSACTION_STARTED(p, i) (CONNECTION(p, i)->is_internal_transaction_started) @@ -406,9 +419,10 @@ typedef enum { #define ACCEPT_FD_SEM 5 #define MAX_REQUEST_QUEUE_SIZE 10 -#define MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION 10 /* time in seconds to keep retrying for a - * watchdog command if the cluster is not - * in stable state */ +#define MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION 10 /* time in seconds to keep + * retrying for a watchdog + * command if the cluster is + * not in stable state */ #define MAX_IDENTIFIER_LEN 128 #define SERIALIZE_ACCEPT (pool_config->serialize_accept == true && \ @@ -422,78 +436,93 @@ typedef enum SemNum SEMNUM_CONFIG, SEMNUM_NODES, SEMNUM_PROCESSES -} SemNum; +} SemNum; /* * up/down request info area in shared memory */ -typedef enum { +typedef enum +{ NODE_UP_REQUEST = 0, NODE_DOWN_REQUEST, NODE_RECOVERY_REQUEST, CLOSE_IDLE_REQUEST, PROMOTE_NODE_REQUEST, NODE_QUARANTINE_REQUEST -} POOL_REQUEST_KIND; +} POOL_REQUEST_KIND; -#define REQ_DETAIL_SWITCHOVER 0x00000001 /* failover due to switch over */ -#define REQ_DETAIL_WATCHDOG 0x00000002 /* failover req from watchdog */ -#define REQ_DETAIL_CONFIRMED 0x00000004 /* failover req that does not require majority vote */ -#define REQ_DETAIL_UPDATE 0x00000008 /* failover req is just and update node status request */ +#define REQ_DETAIL_SWITCHOVER 0x00000001 /* failover due to switch over */ +#define REQ_DETAIL_WATCHDOG 0x00000002 /* failover req from watchdog */ +#define REQ_DETAIL_CONFIRMED 0x00000004 /* failover req that does not + * require majority vote */ +#define REQ_DETAIL_UPDATE 0x00000008 /* failover req is just and update + * node status request */ -typedef struct { - POOL_REQUEST_KIND kind; /* request kind */ +typedef struct +{ + POOL_REQUEST_KIND kind; /* request kind */ unsigned char request_details; /* option flags kind */ - int node_id[MAX_NUM_BACKENDS]; /* request node id */ - int count; /* request node ids count */ -}POOL_REQUEST_NODE; + int node_id[MAX_NUM_BACKENDS]; /* request node id */ + int count; /* request node ids count */ +} POOL_REQUEST_NODE; -typedef struct { +typedef struct +{ POOL_REQUEST_NODE request[MAX_REQUEST_QUEUE_SIZE]; - int request_queue_head; - int request_queue_tail; - int master_node_id; /* the youngest node id which is not in down status */ - int primary_node_id; /* the primary node id in streaming replication mode */ - int conn_counter; - bool switching; /* it true, failover or failback is in progress */ -} POOL_REQUEST_INFO; + int request_queue_head; + int request_queue_tail; + int master_node_id; /* the youngest node id which is not in down + * status */ + int primary_node_id; /* the primary node id in streaming + * replication mode */ + int conn_counter; + bool switching; /* it true, failover or failback is in + * progress */ +} POOL_REQUEST_INFO; /* description of row. corresponding to RowDescription message */ -typedef struct { - char *attrname; /* attribute name */ - int oid; /* 0 or non 0 if it's a table object */ - int attrnumber; /* attribute number starting with 1. 0 if it's not a table */ - int typeoid; /* data type oid */ - int size; /* data length minus means variable data type */ - int mod; /* data type modifier */ -} AttrInfo; - -typedef struct { - int num_attrs; /* number of attributes */ - AttrInfo *attrinfo; -} RowDesc; - -typedef struct { - RowDesc *rowdesc; /* attribute info */ - int numrows; /* number of rows */ - int *nullflags; /* if NULL, -1 or length of the string excluding termination null */ - char **data; /* actual row character data terminated with null */ -} POOL_SELECT_RESULT; +typedef struct +{ + char *attrname; /* attribute name */ + int oid; /* 0 or non 0 if it's a table object */ + int attrnumber; /* attribute number starting with 1. 0 if it's + * not a table */ + int typeoid; /* data type oid */ + int size; /* data length minus means variable data type */ + int mod; /* data type modifier */ +} AttrInfo; + +typedef struct +{ + int num_attrs; /* number of attributes */ + AttrInfo *attrinfo; +} RowDesc; + +typedef struct +{ + RowDesc *rowdesc; /* attribute info */ + int numrows; /* number of rows */ + int *nullflags; /* if NULL, -1 or length of the string + * excluding termination null */ + char **data; /* actual row character data terminated with + * null */ +} POOL_SELECT_RESULT; /* * recovery mode */ -typedef enum { +typedef enum +{ RECOVERY_INIT = 0, RECOVERY_ONLINE, RECOVERY_DETACH, RECOVERY_PROMOTE -} POOL_RECOVERY_MODE; +} POOL_RECOVERY_MODE; /* * global variables */ -extern pid_t mypid; /* parent pid */ +extern pid_t mypid; /* parent pid */ typedef enum { @@ -509,7 +538,7 @@ typedef enum PT_PCP, PT_PCP_WORKER, PT_HEALTH_CHECK -} ProcessType; +} ProcessType; extern ProcessType processType; @@ -521,32 +550,35 @@ typedef enum WAITIG_FOR_CONNECTION, BACKEND_CONNECTING, PROCESSING, - EXITING -} ProcessState; + EXITING +} ProcessState; extern ProcessState processState; -extern POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ -extern volatile sig_atomic_t backend_timer_expired; /* flag for connection closed timer is expired */ -extern volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */ -extern long int weight_master; /* normalized weight of master (0-RAND_MAX range) */ -extern int my_proc_id; /* process table id (!= UNIX's PID) */ -extern ProcessInfo *process_info; /* shmem process information table */ -extern ConnectionInfo *con_info; /* shmem connection info table */ -extern POOL_REQUEST_INFO *Req_info; +extern POOL_CONNECTION_POOL * pool_connection_pool; /* connection pool */ +extern volatile sig_atomic_t backend_timer_expired; /* flag for connection + * closed timer is expired */ +extern volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check + * timer expired */ +extern long int weight_master; /* normalized weight of master (0-RAND_MAX + * range) */ +extern int my_proc_id; /* process table id (!= UNIX's PID) */ +extern ProcessInfo * process_info; /* shmem process information table */ +extern ConnectionInfo * con_info; /* shmem connection info table */ +extern POOL_REQUEST_INFO * Req_info; extern volatile sig_atomic_t *InRecovery; -extern char remote_ps_data[]; /* used for set_ps_display */ +extern char remote_ps_data[]; /* used for set_ps_display */ extern volatile sig_atomic_t got_sighup; extern volatile sig_atomic_t exit_request; #define QUERY_STRING_BUFFER_LEN 1024 -extern char query_string_buffer[]; /* last query string sent to simpleQuery() */ +extern char query_string_buffer[]; /* last query string sent to simpleQuery() */ extern BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS]; -extern char remote_host[]; /* client host */ -extern char remote_port[]; /* client port */ +extern char remote_host[]; /* client host */ +extern char remote_port[]; /* client port */ /* * public functions @@ -556,38 +588,38 @@ extern void register_watchdog_state_change_interupt(void); extern void register_backend_state_sync_req_interupt(void); extern void register_inform_quarantine_nodes_req(void); -extern bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, int count, unsigned char flags); +extern bool register_node_operation_request(POOL_REQUEST_KIND kind, int *node_id_set, int count, unsigned char flags); extern char *get_config_file_name(void); extern char *get_hba_file_name(void); extern void do_child(int *fds); extern void pcp_main(int unix_fd, int inet_fd); -extern int select_load_balancing_node(void); -extern int pool_init_cp(void); -extern POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern int select_load_balancing_node(void); +extern int pool_init_cp(void); +extern POOL_STATUS pool_process_query(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int reset_request); -extern void connection_do_auth(POOL_CONNECTION_POOL_SLOT *cp, char *password); -extern int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); -extern void authenticate_frontend(POOL_CONNECTION *frontend); +extern void connection_do_auth(POOL_CONNECTION_POOL_SLOT * cp, char *password); +extern int pool_do_auth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern int pool_do_reauth(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * cp); +extern void authenticate_frontend(POOL_CONNECTION * frontend); -extern bool is_backend_cache_empty(POOL_CONNECTION_POOL *backend); +extern bool is_backend_cache_empty(POOL_CONNECTION_POOL * backend); /* SSL functionality */ -extern void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp); -extern void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp); -extern void pool_ssl_close(POOL_CONNECTION *cp); -extern int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size); -extern int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size); -extern bool pool_ssl_pending(POOL_CONNECTION *cp); -extern int SSL_ServerSide_init(void); +extern void pool_ssl_negotiate_serverclient(POOL_CONNECTION * cp); +extern void pool_ssl_negotiate_clientserver(POOL_CONNECTION * cp); +extern void pool_ssl_close(POOL_CONNECTION * cp); +extern int pool_ssl_read(POOL_CONNECTION * cp, void *buf, int size); +extern int pool_ssl_write(POOL_CONNECTION * cp, const void *buf, int size); +extern bool pool_ssl_pending(POOL_CONNECTION * cp); +extern int SSL_ServerSide_init(void); -extern POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ErrorResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern void NoticeResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern void NoticeResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); extern void notice_backend_error(int node_id, unsigned char flags); extern bool degenerate_backend_set(int *node_id_set, int count, unsigned char flags); @@ -597,50 +629,50 @@ extern bool send_failback_request(int node_id, bool throw_error, unsigned char f extern void pool_set_timeout(int timeoutval); -extern int pool_check_fd(POOL_CONNECTION *cp); - -extern void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend); - -extern int pool_read_message_length(POOL_CONNECTION_POOL *cp); -extern int *pool_read_message_length2(POOL_CONNECTION_POOL *cp); -extern signed char pool_read_kind(POOL_CONNECTION_POOL *cp); -extern int pool_read_int(POOL_CONNECTION_POOL *cp); - -extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int len, char *contents); -extern POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); - -extern int pool_init_params(ParamStatus *params); -extern void pool_discard_params(ParamStatus *params); -extern char *pool_find_name(ParamStatus *params, char *name, int *pos); -extern int pool_get_param(ParamStatus *params, int index, char **name, char **value); -extern int pool_add_param(ParamStatus *params, char *name, char *value); -extern void pool_param_debug_print(ParamStatus *params); - -extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - int line); -extern void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - int line); -extern void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - char *severity, - int line); -extern void pool_send_readyforquery(POOL_CONNECTION *frontend); -extern void send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp); +extern int pool_check_fd(POOL_CONNECTION * cp); + +extern void pool_send_frontend_exits(POOL_CONNECTION_POOL * backend); + +extern int pool_read_message_length(POOL_CONNECTION_POOL * cp); +extern int *pool_read_message_length2(POOL_CONNECTION_POOL * cp); +extern signed char pool_read_kind(POOL_CONNECTION_POOL * cp); +extern int pool_read_int(POOL_CONNECTION_POOL * cp); + +extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int len, char *contents); +extern POOL_STATUS ParameterStatus(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); + +extern int pool_init_params(ParamStatus * params); +extern void pool_discard_params(ParamStatus * params); +extern char *pool_find_name(ParamStatus * params, char *name, int *pos); +extern int pool_get_param(ParamStatus * params, int index, char **name, char **value); +extern int pool_add_param(ParamStatus * params, char *name, char *value); +extern void pool_param_debug_print(ParamStatus * params); + +extern void pool_send_error_message(POOL_CONNECTION * frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line); +extern void pool_send_fatal_message(POOL_CONNECTION * frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line); +extern void pool_send_severity_message(POOL_CONNECTION * frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + char *severity, + int line); +extern void pool_send_readyforquery(POOL_CONNECTION * frontend); +extern void send_startup_packet(POOL_CONNECTION_POOL_SLOT * cp); extern void pool_free_startup_packet(StartupPacket *sp); extern void child_exit(int code); @@ -654,18 +686,18 @@ extern void pool_semaphore_create(int numSems); extern void pool_semaphore_lock(int semNum); extern void pool_semaphore_unlock(int semNum); -extern BackendInfo *pool_get_node_info(int node_number); -extern int pool_get_node_count(void); +extern BackendInfo * pool_get_node_info(int node_number); +extern int pool_get_node_count(void); extern int *pool_get_process_list(int *array_size); -extern ProcessInfo *pool_get_process_info(pid_t pid); -extern POOL_STATUS OneNode_do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, char *query, char *database); +extern ProcessInfo * pool_get_process_info(pid_t pid); +extern POOL_STATUS OneNode_do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, char *query, char *database); /* child.c */ -extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( - int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); -extern POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection_noerror( - int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); -extern void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp); +extern POOL_CONNECTION_POOL_SLOT * make_persistent_db_connection( + int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); +extern POOL_CONNECTION_POOL_SLOT * make_persistent_db_connection_noerror( + int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry); +extern void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT * cp); /* define pool_system.c */ extern void pool_close_libpq_connection(void); @@ -682,41 +714,41 @@ extern size_t strlcpy(char *dst, const char *src, size_t siz); extern bool update_process_title; extern char **save_ps_display_args(int argc, char **argv); extern void init_ps_display(const char *username, const char *dbname, - const char *host_info, const char *initial_str); + const char *host_info, const char *initial_str); extern void set_ps_display(const char *activity, bool force); extern const char *get_ps_display(int *displen); -extern void pool_ps_idle_display(POOL_CONNECTION_POOL *backend); +extern void pool_ps_idle_display(POOL_CONNECTION_POOL * backend); /* recovery.c */ extern void start_recovery(int recovery_node); extern void finish_recovery(void); -extern int wait_connection_closed(void); +extern int wait_connection_closed(void); /* child.c */ -extern void cancel_request(CancelPacket *sp); +extern void cancel_request(CancelPacket * sp); extern void check_stop_request(void); extern void pool_initialize_private_backend_status(void); extern bool is_session_connected(void); -extern int send_to_pg_frontend(char* data, int len, bool flush); -extern int pg_frontend_exists(void); -extern int set_pg_frontend_blocking(bool blocking); -extern int get_frontend_protocol_version(void); +extern int send_to_pg_frontend(char *data, int len, bool flush); +extern int pg_frontend_exists(void); +extern int set_pg_frontend_blocking(bool blocking); +extern int get_frontend_protocol_version(void); /* pool_process_query.c */ extern void reset_variables(void); extern void reset_connection(void); -extern void per_node_statement_log(POOL_CONNECTION_POOL *backend, int node_id, char *query); -extern void per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, char *query, char *prefix, bool unread); -extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, bool unread, char **message); -extern POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, - char *query, int protoMajor, int pid, int key, int no_ready_for_query); -extern void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int major); -extern void free_select_result(POOL_SELECT_RESULT *result); -extern int compare(const void *p1, const void *p2); -extern void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major); -extern POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp); +extern void per_node_statement_log(POOL_CONNECTION_POOL * backend, int node_id, char *query); +extern void per_node_error_log(POOL_CONNECTION_POOL * backend, int node_id, char *query, char *prefix, bool unread); +extern int pool_extract_error_message(bool read_kind, POOL_CONNECTION * backend, int major, bool unread, char **message); +extern POOL_STATUS do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, + char *query, int protoMajor, int pid, int key, int no_ready_for_query); +extern void do_query(POOL_CONNECTION * backend, char *query, POOL_SELECT_RESULT * *result, int major); +extern void free_select_result(POOL_SELECT_RESULT * result); +extern int compare(const void *p1, const void *p2); +extern void do_error_execute_command(POOL_CONNECTION_POOL * backend, int node_id, int major); +extern POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL * cp); extern void pool_dump_valid_backend(int backend_id); -extern bool pool_push_pending_data(POOL_CONNECTION *backend); +extern bool pool_push_pending_data(POOL_CONNECTION * backend); /* pool_auth.c */ extern void pool_random_salt(char *md5Salt); @@ -728,51 +760,51 @@ extern char *get_pool_key(void); /* pool_worker_child.c */ extern void do_worker_child(void); -extern int get_query_result(POOL_CONNECTION_POOL_SLOT **slots, int backend_id, char *query, POOL_SELECT_RESULT **res); +extern int get_query_result(POOL_CONNECTION_POOL_SLOT * *slots, int backend_id, char *query, POOL_SELECT_RESULT * *res); /* md5.c */ extern bool pg_md5_encrypt(const char *passwd, const char *salt, size_t salt_len, char *buf); /* pool_connection_pool.c */ -extern int pool_init_cp(void); -extern POOL_CONNECTION_POOL *pool_create_cp(void); -extern POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket); +extern int pool_init_cp(void); +extern POOL_CONNECTION_POOL * pool_create_cp(void); +extern POOL_CONNECTION_POOL * pool_get_cp(char *user, char *database, int protoMajor, int check_socket); extern void pool_discard_cp(char *user, char *database, int protoMajor); extern void pool_backend_timer(void); -extern void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend); +extern void pool_connection_pool_timer(POOL_CONNECTION_POOL * backend); extern RETSIGTYPE pool_backend_timer_handler(int sig); -extern int connect_inet_domain_socket(int slot, bool retry); -extern int connect_unix_domain_socket(int slot, bool retry); -extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry); -extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry); -extern int pool_pool_index(void); +extern int connect_inet_domain_socket(int slot, bool retry); +extern int connect_unix_domain_socket(int slot, bool retry); +extern int connect_inet_domain_socket_by_port(char *host, int port, bool retry); +extern int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry); +extern int pool_pool_index(void); /* utils/statistics.c */ -size_t stat_shared_memory_size(void); -void stat_set_stat_area(void *address); -void stat_init_stat_area(void); -void stat_count_up(int backend_node_id, Node *parsetree); -uint64 stat_get_select_count(int backend_node_id); +size_t stat_shared_memory_size(void); +void stat_set_stat_area(void *address); +void stat_init_stat_area(void); +void stat_count_up(int backend_node_id, Node *parsetree); +uint64 stat_get_select_count(int backend_node_id); -extern int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps); +extern int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps); /* pcp_child.c */ -extern int send_to_pcp_frontend(char* data, int len, bool flush); -extern int pcp_frontend_exists(void); +extern int send_to_pcp_frontend(char *data, int len, bool flush); +extern int pcp_frontend_exists(void); extern void pcp_worker_main(int port); extern void pcp_mark_recovery_finished(void); extern bool pcp_mark_recovery_in_progress(void); /* pgpool_main.c */ -extern int pool_send_to_frontend(char* data, int len, bool flush); -extern int pool_frontend_exists(void); +extern int pool_send_to_frontend(char *data, int len, bool flush); +extern int pool_frontend_exists(void); extern pid_t pool_waitpid(int *status); -extern int write_status_file(void); +extern int write_status_file(void); extern void do_health_check_child(int *node_id); -extern POOL_NODE_STATUS *verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots); -extern POOL_NODE_STATUS *pool_get_node_status(void); +extern POOL_NODE_STATUS * verify_backend_node_status(POOL_CONNECTION_POOL_SLOT * *slots); +extern POOL_NODE_STATUS * pool_get_node_status(void); extern void pool_set_backend_status_changed_time(int backend_id); -extern int get_next_master_node(void); +extern int get_next_master_node(void); -#endif /* POOL_H */ +#endif /* POOL_H */ diff --git a/src/include/pool_config.h b/src/include/pool_config.h index 0194f9172..32b9b1c84 100644 --- a/src/include/pool_config.h +++ b/src/include/pool_config.h @@ -45,41 +45,42 @@ #include <regex.h> #define BLACKLIST 0 #define WHITELIST 1 -#define PATTERN_ARR_SIZE 16 /* Default length of regex array: 16 patterns */ -typedef struct { - char *pattern; - int type; - int flag; - regex_t regexv; -} RegPattern; +#define PATTERN_ARR_SIZE 16 /* Default length of regex array: 16 patterns */ +typedef struct +{ + char *pattern; + int type; + int flag; + regex_t regexv; +} RegPattern; typedef enum MasterSlaveSubModes { SLONY_MODE = 1, STREAM_MODE, LOGICAL_MODE -}MasterSlaveSubModes; +} MasterSlaveSubModes; typedef enum LogStandbyDelayModes { LSD_ALWAYS = 1, LSD_OVER_THRESHOLD, LSD_NONE -}LogStandbyDelayModes; +} LogStandbyDelayModes; typedef enum MemCacheMethod { SHMEM_CACHE = 1, MEMCACHED_CACHE -}MemCacheMethod; +} MemCacheMethod; typedef enum WdLifeCheckMethod { LIFECHECK_BY_QUERY = 1, LIFECHECK_BY_HB, LIFECHECK_BY_EXTERNAL -}WdLifeCheckMethod; +} WdLifeCheckMethod; typedef enum DLBOW_OPTION { @@ -87,7 +88,7 @@ typedef enum DLBOW_OPTION DLBOW_TRANSACTION, DLBOW_TRANS_TRANSACTION, DLBOW_ALWAYS -} DLBOW_OPTION; +} DLBOW_OPTION; /* * Flags for backendN_flag @@ -100,23 +101,26 @@ typedef enum DLBOW_OPTION /* * watchdog list */ -typedef struct WdRemoteNodeInfo { - char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ - int pgpool_port; /* pgpool port */ - int wd_port; /* watchdog port */ -} WdRemoteNodeInfo; +typedef struct WdRemoteNodeInfo +{ + char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ + int pgpool_port; /* pgpool port */ + int wd_port; /* watchdog port */ +} WdRemoteNodeInfo; -typedef struct WdRemoteNodesConfig{ - int num_wd; /* number of watchdogs */ - WdRemoteNodeInfo wd_remote_node_info[MAX_WATCHDOG_NUM]; -} WdRemoteNodesConfig; +typedef struct WdRemoteNodesConfig +{ + int num_wd; /* number of watchdogs */ + WdRemoteNodeInfo wd_remote_node_info[MAX_WATCHDOG_NUM]; +} WdRemoteNodesConfig; -typedef struct { - char addr[WD_MAX_HOST_NAMELEN]; - char if_name[WD_MAX_IF_NAME_LEN]; - int dest_port; -} WdHbIf; +typedef struct +{ + char addr[WD_MAX_HOST_NAMELEN]; + char if_name[WD_MAX_IF_NAME_LEN]; + int dest_port; +} WdHbIf; #define WD_INFO(wd_id) (pool_config->wd_remote_nodes.wd_remote_node_info[(wd_id)]) #define WD_HB_IF(if_id) (pool_config->hb_if[(if_id)]) @@ -124,254 +128,369 @@ typedef struct { /* * Per node health check parameters */ -typedef struct { - 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 */ -} HealthCheckParams; +typedef struct +{ + 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 */ +} HealthCheckParams; /* * configuration parameters */ -typedef struct { - 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 */ - 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 */ - bool allow_clear_text_frontend_auth; - /* enable Pgpool-II to use clear text password authentication - * between Pgpool and client to get the password - * when password for user does not exist in pool_password - * file. - */ - 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_str; /* log destination: stderr and/or syslog */ - int log_destination; /* log destination */ - 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 **black_query_pattern_list; /* list of query patterns that should be sent to primary node */ - 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 */ - HealthCheckParams *health_check_params; /* per node health check parameters */ - 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. - */ - bool detach_false_primary; /* If true, detach false primary */ - 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 - */ - 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 */ - bool log_client_messages; /* If true, logs any client messages */ - char *lobj_lock_table; /* table name to lock for rewriting lo_creat */ - - 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 */ +typedef struct +{ + 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 */ + 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 */ + bool allow_clear_text_frontend_auth; + + /* + * enable Pgpool-II to use clear text password authentication between + * Pgpool and client to get the password when password for user does not + * exist in pool_password file. + */ + 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_str; /* log destination: stderr and/or + * syslog */ + int log_destination; /* log destination */ + 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 **black_query_pattern_list; /* list of query patterns that + * should be sent to primary node */ + 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 */ + HealthCheckParams *health_check_params; /* per node health check + * parameters */ + 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. */ + bool detach_false_primary; /* If true, detach false primary */ + 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 */ + 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 */ + bool log_client_messages; /* If true, logs any client messages */ + char *lobj_lock_table; /* table name to lock for rewriting + * lo_creat */ + + 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 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_black_query_pattern_list; /* number of query patterns in black_query_pattern_list */ - int num_wd_monitoring_interfaces_list; /* number of items in wd_monitoring_interfaces_list */ + 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_black_query_pattern_list; /* number of query patterns in + * black_query_pattern_list */ + int num_wd_monitoring_interfaces_list; /* number of items in + * wd_monitoring_interfaces_list */ /* ssl configuration */ - 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 */ - - 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 */ - - RegPattern *lists_query_patterns; /* Precompiled regex patterns for black query pattern lists */ - int query_pattc; /* number of regexp pattern */ - int current_query_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 */ + 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 */ + + 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 */ + + RegPattern *lists_query_patterns; /* Precompiled regex patterns for + * black query pattern lists */ + int query_pattc; /* number of regexp pattern */ + int current_query_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 */ /* - * database_redirect_preference_list = 'postgres:primary,mydb[0-4]:1,mydb[5-9]:2' + * 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 */ + 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 */ /* - * app_name_redirect_preference_list = 'psql:primary,myapp[0-4]:1,myapp[5-9]:standby' + * 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 */ - - 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. - */ - - DLBOW_OPTION disable_load_balance_on_write; /* Load balance behavior when write query is issued - * in an explicit transaction. - * Note that any query not in an explicit transaction - * is not affected by the parameter. - * 'transaction' (the default): if a write query is issued, - * subsequent read queries will not be load balanced - * until the transaction ends. - * 'trans_transaction': if a write query is issued, - * subsequent read queries in an explicit transaction - * will not be load balanced until the session ends. - */ + 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 */ + + 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. */ + + DLBOW_OPTION disable_load_balance_on_write; /* Load balance behavior when + * write query is issued in an + * explicit transaction. Note + * that any query not in an + * explicit transaction is not + * affected by the parameter. + * 'transaction' (the + * default): if a write query + * is issued, subsequent read + * queries will not be load + * balanced until the + * transaction ends. + * 'trans_transaction': if a + * write query is issued, + * subsequent read queries in + * an explicit transaction + * will not be load balanced + * until the session ends. */ /* * add for watchdog */ - bool use_watchdog; /* Enables watchdog */ - bool failover_when_quorum_exists; /* Do failover only when wd cluster holds the quorum */ - bool failover_require_consensus; /* Only do failover when majority aggrees */ - bool allow_multiple_failover_requests_from_node; /* One Pgpool-II node can send multiple - * failover requests to build consensus - */ - 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*/ + bool use_watchdog; /* Enables watchdog */ + bool failover_when_quorum_exists; /* Do failover only when wd + * cluster holds the quorum */ + bool failover_require_consensus; /* Only do failover when majority + * aggrees */ + bool allow_multiple_failover_requests_from_node; /* One Pgpool-II node + * can send multiple + * failover requests to + * build consensus */ + 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; - -extern POOL_CONFIG* pool_config; + 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; + +extern POOL_CONFIG * pool_config; typedef enum { @@ -380,7 +499,7 @@ typedef enum CFGCXT_RELOAD, CFGCXT_PCP, CFGCXT_SESSION -} ConfigContext; +} ConfigContext; typedef struct ConfigVariable { @@ -391,16 +510,16 @@ typedef struct ConfigVariable } ConfigVariable; -extern int pool_init_config(void); +extern int pool_init_config(void); extern bool pool_get_config(const char *config_file, ConfigContext context); -extern int eval_logical(const char *str); +extern int eval_logical(const char *str); extern char *pool_flag_to_str(unsigned short flag); -extern char* backend_status_to_str(BackendInfo *bi); +extern char *backend_status_to_str(BackendInfo * bi); /* methods used for regexp support */ -extern int add_regex_pattern(const char *type, char *s); -extern int growFunctionPatternArray(RegPattern item); -extern int growMemqcacheTablePatternArray(RegPattern item); -extern int growQueryPatternArray(RegPattern item); +extern int add_regex_pattern(const char *type, char *s); +extern int growFunctionPatternArray(RegPattern item); +extern int growMemqcacheTablePatternArray(RegPattern item); +extern int growQueryPatternArray(RegPattern item); -#endif /* POOL_CONFIG_H */ +#endif /* POOL_CONFIG_H */ diff --git a/src/include/pool_config_variables.h b/src/include/pool_config_variables.h index 4224b5f9a..7bf4f51be 100644 --- a/src/include/pool_config_variables.h +++ b/src/include/pool_config_variables.h @@ -43,7 +43,7 @@ typedef enum WATCHDOG_LIFECHECK, GENERAL_CONFIG, CACHE_CONFIG -} config_group; +} config_group; typedef enum { @@ -58,7 +58,7 @@ typedef enum CONFIG_VAR_TYPE_DOUBLE_ARRAY, CONFIG_VAR_TYPE_STRING_ARRAY, CONFIG_VAR_TYPE_GROUP -}config_type; +} config_type; /* * The possible values of an enum variable are specified by an array of @@ -86,10 +86,13 @@ typedef enum /* Config variable flags bit values */ #define VAR_PART_OF_GROUP 0x0001 #define VAR_HIDDEN_VALUE 0x0002 /* for password type variables */ -#define VAR_HIDDEN_IN_SHOW_ALL 0x0004 /* for variables hidden in show all*/ -#define VAR_NO_RESET_ALL 0x0008 /* for variables not to be reset with reset all*/ -#define ARRAY_VAR_ALLOW_NO_INDEX 0x0010 /* for array type vars that also alows - * variable with same naem with out index*/ +#define VAR_HIDDEN_IN_SHOW_ALL 0x0004 /* for variables hidden in show + * all */ +#define VAR_NO_RESET_ALL 0x0008 /* for variables not to be reset + * with reset all */ +#define ARRAY_VAR_ALLOW_NO_INDEX 0x0010 /* for array type vars that also + * alows variable with same naem + * with out index */ #define DEFAULT_FOR_NO_VALUE_ARRAY_VAR 0x0020 /* @@ -103,44 +106,52 @@ typedef bool (*IndexedVarEmptySlotCheck) (int index); 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 (*ConfigStringListAssignFunc) (ConfigContext scontext, char *newval, int index); -typedef bool (*ConfigInt64AssignFunc) (ConfigContext scontext, int64 newval, int elevel); +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 (*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 (*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 elevel); -typedef bool (*ConfigEnumProcessingFunc) (int newval,int elevel); +typedef bool (*ConfigStringProcessingFunc) (char *newval, int elevel); +typedef bool (*ConfigEnumProcessingFunc) (int newval, int elevel); 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 flags; /* flags */ - int max_elements; /* number of maximum elements, only valid for array type configs */ - int status; /* status bits, see below */ - int sourceline; /* line in source file */ - - - GucSource *sources; /* source of the current actual value, For array type config elements - * it contains the corosponding source of each individual element */ - GucSource *reset_sources; /* source of the reset value, For array type config elements - * it contains the corosponding source of each individual element */ - ConfigContext *scontexts; /* context that set the current value, For array type config elements - * it contains the corosponding context of each individual element */ + 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 flags; /* flags */ + int max_elements; /* number of maximum elements, only valid for + * array type configs */ + int status; /* status bits, see below */ + int sourceline; /* line in source file */ + + + GucSource *sources; /* source of the current actual value, For + * array type config elements it contains the + * corosponding source of each individual + * element */ + GucSource *reset_sources; /* source of the reset value, For array type + * config elements it contains the + * corosponding source of each individual + * element */ + ConfigContext *scontexts; /* context that set the current value, For + * array type config elements it contains the + * corosponding context of each individual + * element */ }; @@ -170,33 +181,34 @@ struct config_int ConfigIntAssignFunc assign_func; ConfigIntAssignFunc check_func; VarShowHook show_hook; - int reset_val; + int reset_val; }; struct config_int_array { struct config_generic gen; /* constant fields, must be set correctly in initial value: */ - int **variable; + int **variable; int boot_val; int min; int max; - struct config_int config_no_index; /* int type record if the array also includes - * master value (value without index postfix )*/ + struct config_int config_no_index; /* int type record if the array also + * includes master value (value + * without index postfix ) */ ConfigIntArrayAssignFunc assign_func; ConfigIntArrayAssignFunc check_func; IndexedVarShowHook show_hook; - IndexedVarEmptySlotCheck empty_slot_check_func; - int *reset_vals; /* Array of reset values */ + IndexedVarEmptySlotCheck empty_slot_check_func; + 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 *variable; double boot_val; double min; double max; @@ -210,25 +222,26 @@ struct config_double_array { struct config_generic gen; /* constant fields, must be set correctly in initial value: */ - double **variable; + double **variable; double boot_val; double min; double max; - struct config_double config_no_index; /* record if the array also includes - * master value (value without index postfix )*/ + struct config_double config_no_index; /* record if the array also + * includes master value (value + * without index postfix ) */ ConfigDoubleArrayAssignFunc assign_func; ConfigDoubleArrayAssignFunc check_func; IndexedVarShowHook show_hook; - IndexedVarEmptySlotCheck empty_slot_check_func; - double *reset_vals; + IndexedVarEmptySlotCheck empty_slot_check_func; + double *reset_vals; }; struct config_long { struct config_generic gen; /* constant fields, must be set correctly in initial value: */ - int64 *variable; + int64 *variable; int64 boot_val; int64 min; int64 max; @@ -248,39 +261,40 @@ struct config_string ConfigStringAssignFunc check_func; ConfigStringProcessingFunc process_func; VarShowHook show_hook; - char* reset_val; + 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; + char ***variable; + const char *boot_val; - struct config_string config_no_index; /* record if the array also includes - * master value (value without index postfix )*/ + struct config_string config_no_index; /* record if the array also + * includes master value (value + * without index postfix ) */ ConfigStringArrayAssignFunc assign_func; ConfigStringArrayAssignFunc check_func; IndexedVarShowHook show_hook; - IndexedVarEmptySlotCheck empty_slot_check_func; - char **reset_vals; + IndexedVarEmptySlotCheck empty_slot_check_func; + 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; - const char *seperator; + char ***variable; + int *list_elements_count; + const char *boot_val; + const char *seperator; bool compute_regex; ConfigStringListAssignFunc assign_func; ConfigStringListAssignFunc check_func; VarShowHook show_hook; - char *reset_val; - char *current_val; + char *reset_val; + char *current_val; }; struct config_enum @@ -294,30 +308,30 @@ struct config_enum ConfigEnumAssignFunc check_func; ConfigEnumProcessingFunc process_func; VarShowHook show_hook; - int reset_val; + int reset_val; }; struct config_grouped_array_var { struct config_generic gen; - int var_count; + int var_count; struct config_generic **var_list; }; extern void InitializeConfigOptions(void); extern bool set_one_config_option(const char *name, const char *value, - ConfigContext context, GucSource source, int elevel); + ConfigContext context, GucSource source, int elevel); extern bool set_config_options(ConfigVariable *head_p, - ConfigContext context, GucSource source, int elevel); + ConfigContext context, GucSource source, int elevel); #ifndef POOL_PRIVATE -extern bool report_config_variable(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* var_name); -extern bool report_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern bool set_config_option_for_session(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char *name, const char *value); -bool reset_all_variables(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern bool report_config_variable(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *var_name); +extern bool report_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern bool set_config_option_for_session(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value); +bool reset_all_variables(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); #endif -#endif /* POOL_CONFIG_VARIABLES_H */ +#endif /* POOL_CONFIG_VARIABLES_H */ diff --git a/src/include/pool_type.h b/src/include/pool_type.h index 494f6300f..43f29a595 100644 --- a/src/include/pool_type.h +++ b/src/include/pool_type.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2015 PgPool Global Development Group @@ -35,8 +35,8 @@ #ifdef c_plusplus #ifndef __cplusplus #define __cplusplus -#endif /* __cplusplus */ -#endif /* c_plusplus */ +#endif /* __cplusplus */ +#endif /* c_plusplus */ #ifndef __BEOS__ #ifndef __cplusplus @@ -55,8 +55,8 @@ typedef char bool; #ifndef FALSE #define FALSE ((bool) 0) #endif -#endif /* not C++ */ -#endif /* __BEOS__ */ +#endif /* not C++ */ +#endif /* __BEOS__ */ /* ---------------------------------------------------------------- * Section 5: offsetof, lengthof, endof, alignment @@ -104,15 +104,16 @@ typedef unsigned long long int uint64; #error must have a working 64-bit integer datatype #endif -typedef enum { +typedef enum +{ LOAD_UNSELECTED = 0, LOAD_SELECTED -} LOAD_BALANCE_STATUS; +} LOAD_BALANCE_STATUS; -extern int assert_enabled; +extern int assert_enabled; extern void ExceptionalCondition(const char *conditionName, - const char *errorType, - const char *fileName, int lineNumber) __attribute__((noreturn)); + const char *errorType, + const char *fileName, int lineNumber) __attribute__((noreturn)); #define MAXIMUM_ALIGNOF 8 @@ -137,15 +138,15 @@ extern void ExceptionalCondition(const char *conditionName, #define ss_family __ss_family #else #error struct sockaddr_storage does not provide an ss_family member -#endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */ -#endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY */ +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */ +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY */ #ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN #define ss_len __ss_len #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 -#endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN */ +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN */ -#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ +#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */ /* Define a struct sockaddr_storage if we don't have one. */ struct sockaddr_storage @@ -153,10 +154,11 @@ struct sockaddr_storage union { struct sockaddr sa; /* get the system-dependent fields */ - long int ss_align; /* ensures struct is properly aligned. original uses int64 */ - char ss_pad[128]; /* ensures struct has desired size */ + long int ss_align; /* ensures struct is properly aligned. + * original uses int64 */ + char ss_pad[128]; /* ensures struct has desired size */ } - ss_stuff; + ss_stuff; }; #define ss_family ss_stuff.sa.sa_family @@ -165,32 +167,34 @@ struct sockaddr_storage #define ss_len ss_stuff.sa.sa_len #define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1 #endif -#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ +#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */ typedef struct { struct sockaddr_storage addr; - /* ACCEPT_TYPE_ARG3 - Third argument type of accept(). - * It is defined in ac_func_accept_argtypes.m4 + + /* + * ACCEPT_TYPE_ARG3 - Third argument type of accept(). It is defined in + * ac_func_accept_argtypes.m4 */ ACCEPT_TYPE_ARG3 salen; } SockAddr; -#define AUTH_REQ_OK 0 /* User is authenticated */ -#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ -#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ -#define AUTH_REQ_PASSWORD 3 /* Password */ -#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ -#define AUTH_REQ_MD5 5 /* md5 password */ -#define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */ -#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ -#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ -#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ -#define AUTH_REQ_SASL 10 /* Begin SASL authentication */ -#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */ -#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */ +#define AUTH_REQ_OK 0 /* User is authenticated */ +#define AUTH_REQ_KRB4 1 /* Kerberos V4. Not supported any more. */ +#define AUTH_REQ_KRB5 2 /* Kerberos V5. Not supported any more. */ +#define AUTH_REQ_PASSWORD 3 /* Password */ +#define AUTH_REQ_CRYPT 4 /* crypt password. Not supported any more. */ +#define AUTH_REQ_MD5 5 /* md5 password */ +#define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */ +#define AUTH_REQ_GSS 7 /* GSSAPI without wrap() */ +#define AUTH_REQ_GSS_CONT 8 /* Continue GSS exchanges */ +#define AUTH_REQ_SSPI 9 /* SSPI negotiate without wrap() */ +#define AUTH_REQ_SASL 10 /* Begin SASL authentication */ +#define AUTH_REQ_SASL_CONT 11 /* Continue SASL authentication */ +#define AUTH_REQ_SASL_FIN 12 /* Final SASL message */ typedef unsigned int AuthRequest; @@ -211,7 +215,7 @@ typedef unsigned int AuthRequest; #define STATIC_IF_INLINE static inline #else #define STATIC_IF_INLINE -#endif /* PG_USE_INLINE */ +#endif /* PG_USE_INLINE */ typedef uint8 bits8; /* >= 8 bits */ @@ -240,6 +244,7 @@ typedef size_t Size; typedef unsigned long Datum; /* XXX sizeof(long) >= sizeof(void *) */ typedef void (*pg_on_exit_callback) (int code, Datum arg); + /* * NULL * Null pointer. @@ -316,7 +321,7 @@ typedef void (*pg_on_exit_callback) (int code, Datum arg); #define AssertState(condition) \ Trap(!(condition), "BadState") -#endif /* USE_ASSERT_CHECKING && !FRONTEND */ +#endif /* USE_ASSERT_CHECKING && !FRONTEND */ /* @@ -343,7 +348,7 @@ typedef void (*pg_on_exit_callback) (int code, Datum arg); ((void) sizeof(struct { int static_assert_failure : (condition) ? 1 : -1; })) #define StaticAssertExpr(condition, errmessage) \ StaticAssertStmt(condition, errmessage) -#endif /* HAVE__STATIC_ASSERT */ +#endif /* HAVE__STATIC_ASSERT */ /* @@ -371,7 +376,7 @@ typedef void (*pg_on_exit_callback) (int code, Datum arg); #define AssertVariableIsOfTypeMacro(varname, typename) \ ((void) StaticAssertExpr(sizeof(varname) == sizeof(typename), \ CppAsString(varname) " does not have type " CppAsString(typename))) -#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ +#endif /* HAVE__BUILTIN_TYPES_COMPATIBLE_P */ /* * StrNCpy * Like standard library function strncpy(), except that result string @@ -495,4 +500,4 @@ typedef void (*pg_on_exit_callback) (int code, Datum arg); } while (0) -#endif /* POOL_TYPE_H */ +#endif /* POOL_TYPE_H */ diff --git a/src/include/protocol/pool_proto_modules.h b/src/include/protocol/pool_proto_modules.h index 0916eee19..d8bd3a64c 100644 --- a/src/include/protocol/pool_proto_modules.h +++ b/src/include/protocol/pool_proto_modules.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2017 PgPool Global Development Group @@ -38,154 +38,157 @@ #define POOL_DUMMY_READ_QUERY "SELECT 'pgpool: unable to parse the query'" #define POOL_ERROR_QUERY "send invalid query from pgpool to abort transaction" -extern char *copy_table; /* copy table name */ -extern char *copy_schema; /* copy table name */ -extern char copy_delimiter; /* copy delimiter char */ -extern char *copy_null; /* copy null string */ +extern char *copy_table; /* copy table name */ +extern char *copy_schema; /* copy table name */ +extern char copy_delimiter; /* copy delimiter char */ +extern char *copy_null; /* copy null string */ -extern int is_select_pgcatalog; -extern int is_select_for_update; /* also for SELECT ... INTO */ +extern int is_select_pgcatalog; +extern int is_select_for_update; /* also for SELECT ... INTO */ extern char *parsed_query; /* * modules defined in pool_proto_modules.c */ -extern POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS SimpleQuery(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS Execute(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS Execute(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS Parse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS Parse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS Bind(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS Bind(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS Describe(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS Describe(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS Close(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS Close(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS FunctionCall3(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents); -extern POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, bool send_ready, bool cache_commit); +extern POOL_STATUS ReadyForQuery(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, bool send_ready, bool cache_commit); -extern POOL_STATUS ParseComplete(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ParseComplete(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS BindComplete(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS BindComplete(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS CloseComplete(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS CloseComplete(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS ParameterDescription(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ParameterDescription(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ErrorResponse3(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS CopyInResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS CopyOutResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, int copyin); +extern POOL_STATUS CopyDataRows(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int copyin); -extern POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS FunctionCall(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS ProcessBackendResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int *state, short *num_fields); -extern void handle_query_context(POOL_CONNECTION_POOL *backend);; +extern void handle_query_context(POOL_CONNECTION_POOL * backend);; /* * modules defined in pool_proto2.c */ -extern POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS AsciiRow(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, short num_fields); -extern POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS BinaryRow(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, short num_fields); -extern POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS CompletedResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS CursorResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern void EmptyQueryResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern void EmptyQueryResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS FunctionResultResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); +extern POOL_STATUS NotificationResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); -extern int RowDescription(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short *result); +extern int RowDescription(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + short *result); -extern void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion, int pid, int key); -extern POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion); +extern void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion, int pid, int key); +extern POOL_STATUS wait_for_query_response(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion); extern bool is_select_query(Node *node, char *sql); extern bool is_commit_query(Node *node); extern bool is_rollback_query(Node *node); extern bool is_commit_or_rollback_query(Node *node); -extern bool is_strict_query(Node *node); /* returns non 0 if this is strict query */ -extern int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node); -extern POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *query, InsertStmt *node, int lock_kind); +extern bool is_strict_query(Node *node); /* returns non 0 if this is strict + * query */ +extern int need_insert_lock(POOL_CONNECTION_POOL * backend, char *query, Node *node); +extern POOL_STATUS insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *query, InsertStmt *node, int lock_kind); extern char *parse_copy_data(char *buf, int len, char delimiter, int col_id); -extern int check_copy_from_stdin(Node *node); /* returns non 0 if this is a COPY FROM STDIN */ -extern void query_ps_status(char *query, POOL_CONNECTION_POOL *backend); /* show ps status */ -extern POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node); -extern POOL_STATUS end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern int detect_deadlock_error(POOL_CONNECTION *master, int major); -extern int detect_serialization_error(POOL_CONNECTION *master, int major, bool unread); -extern int detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major); -extern int detect_query_cancel_error(POOL_CONNECTION *backend, int major); -extern bool is_partition_table(POOL_CONNECTION_POOL *backend, Node *node); -extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp); -extern void query_cache_register(char kind, POOL_CONNECTION *frontend, char *database, char *data, int data_len); -extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP DATABASE command */ - -extern void send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major); -extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, +extern int check_copy_from_stdin(Node *node); /* returns non 0 if this is a + * COPY FROM STDIN */ +extern void query_ps_status(char *query, POOL_CONNECTION_POOL * backend); /* show ps status */ +extern POOL_STATUS start_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, Node *node); +extern POOL_STATUS end_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern int detect_deadlock_error(POOL_CONNECTION * master, int major); +extern int detect_serialization_error(POOL_CONNECTION * master, int major, bool unread); +extern int detect_active_sql_transaction_error(POOL_CONNECTION * backend, int major); +extern int detect_query_cancel_error(POOL_CONNECTION * backend, int major); +extern bool is_partition_table(POOL_CONNECTION_POOL * backend, Node *node); +extern POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL * cp); +extern void query_cache_register(char kind, POOL_CONNECTION * frontend, char *database, char *data, int data_len); +extern int is_drop_database(Node *node); /* returns non 0 if this is a DROP + * DATABASE command */ + +extern void send_simplequery_message(POOL_CONNECTION * backend, int len, char *string, int major); +extern POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL * backend, int node_id, char *kind, int len, char *string); -extern int synchronize(POOL_CONNECTION *cp); -extern void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *decided_kind); -extern void read_kind_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *kind, int node); -extern void do_error_command(POOL_CONNECTION *backend, int major); -extern void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend); +extern int synchronize(POOL_CONNECTION * cp); +extern void read_kind_from_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *decided_kind); +extern void read_kind_from_one_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *kind, int node); +extern void do_error_command(POOL_CONNECTION * backend, int major); +extern void raise_intentional_error_if_need(POOL_CONNECTION_POOL * backend); -extern void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void pool_at_command_success(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); /* * modules defined in CommandComplete.c */ -extern POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool command_complete); +extern POOL_STATUS CommandComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, bool command_complete); #endif diff --git a/src/include/query_cache/pool_memqcache.h b/src/include/query_cache/pool_memqcache.h index 63e1e71ab..ee0d23bac 100644 --- a/src/include/query_cache/pool_memqcache.h +++ b/src/include/query_cache/pool_memqcache.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group @@ -32,52 +32,56 @@ #define NO_QUERY_CACHE "/*NO QUERY CACHE*/" #define NO_QUERY_CACHE_COMMENT_SZ (sizeof(NO_QUERY_CACHE)-1) -#define POOL_MD5_HASHKEYLEN 32 /* MD5 hash key length */ +#define POOL_MD5_HASHKEYLEN 32 /* MD5 hash key length */ /* * On memory query cache on shmem is divided into fixed length "cache * block". Each block is assigned a "cache block id", which is * starting with 0. */ -typedef char *POOL_CACH_BLOCK; /* pointer to cache block */ -typedef unsigned int POOL_CACHE_BLOCKID; /* cache block id */ -typedef unsigned int POOL_CACHE_ITEMID; /* cache item id */ +typedef char *POOL_CACH_BLOCK; /* pointer to cache block */ +typedef unsigned int POOL_CACHE_BLOCKID; /* cache block id */ +typedef unsigned int POOL_CACHE_ITEMID; /* cache item id */ /* * "Cache id" represents "absolute address" of a cache item. */ -typedef struct { - POOL_CACHE_BLOCKID blockid; - POOL_CACHE_ITEMID itemid; -} POOL_CACHEID; /* cache id */ +typedef struct +{ + POOL_CACHE_BLOCKID blockid; + POOL_CACHE_ITEMID itemid; +} POOL_CACHEID; /* cache id */ /* * Each block has management space called "cache block header" at the * very beginning of the cache block. */ -#define POOL_BLOCK_USED 0x0001 /* is this block used? */ +#define POOL_BLOCK_USED 0x0001 /* is this block used? */ -typedef struct { +typedef struct +{ unsigned char flags; /* flags. see above */ unsigned int num_items; /* number of items */ - unsigned int free_bytes; /* total free space in bytes */ -} POOL_CACHE_BLOCK_HEADER; + unsigned int free_bytes; /* total free space in bytes */ +} POOL_CACHE_BLOCK_HEADER; -typedef struct { - char query_hash[POOL_MD5_HASHKEYLEN]; -} POOL_QUERY_HASH; +typedef struct +{ + char query_hash[POOL_MD5_HASHKEYLEN]; +} POOL_QUERY_HASH; -#define POOL_ITEM_USED 0x0001 /* is this item used? */ -#define POOL_ITEM_HAS_NEXT 0x0002 /* is this item has "next" item? */ -#define POOL_ITEM_DELETED 0x0004 /* is this item deleted? */ +#define POOL_ITEM_USED 0x0001 /* is this item used? */ +#define POOL_ITEM_HAS_NEXT 0x0002 /* is this item has "next" item? */ +#define POOL_ITEM_DELETED 0x0004 /* is this item deleted? */ -typedef struct { - POOL_QUERY_HASH query_hash; /* md5 hashed query signature */ +typedef struct +{ + POOL_QUERY_HASH query_hash; /* md5 hashed query signature */ POOL_CACHEID next; /* next cache item if any */ unsigned int offset; /* item offset in this block */ unsigned char flags; /* flags. see above */ -} POOL_CACHE_ITEM_POINTER; +} POOL_CACHE_ITEM_POINTER; /* * Each block holds several "cache item", which consists of variable @@ -95,15 +99,17 @@ typedef struct { /* * "Cache Item header" structure is used to manage each cache item. */ -typedef struct { +typedef struct +{ unsigned int total_length; /* total length in bytes including myself */ - time_t timestamp; /* cache creation time */ -} POOL_CACHE_ITEM_HEADER; + time_t timestamp; /* cache creation time */ +} POOL_CACHE_ITEM_HEADER; -typedef struct { - POOL_CACHE_ITEM_HEADER header; /* cache item header */ - char data[1]; /* variable length data follows */ -} POOL_CACHE_ITEM; +typedef struct +{ + POOL_CACHE_ITEM_HEADER header; /* cache item header */ + char data[1]; /* variable length data follows */ +} POOL_CACHE_ITEM; /* * Possible the largest free space size in bytes @@ -115,51 +121,53 @@ typedef struct { #define MAX_VALUE 8192 #define MAX_KEY 256 -extern int memcached_connect(void); +extern int memcached_connect(void); extern void memcached_disconnect(void); -extern void memqcache_register(char kind, POOL_CONNECTION *frontend, char *data, int data_len); +extern void memqcache_register(char kind, POOL_CONNECTION * frontend, char *data, int data_len); /* * Cache key */ typedef union { - POOL_CACHEID cacheid; /* cache key (shmem configuration) */ - char hashkey[POOL_MD5_HASHKEYLEN]; /* cache key (memcached configuration) */ -} POOL_CACHEKEY; + POOL_CACHEID cacheid; /* cache key (shmem configuration) */ + char hashkey[POOL_MD5_HASHKEYLEN]; /* cache key (memcached + * configuration) */ +} POOL_CACHEKEY; /* * Internal buffer structure */ typedef struct { - size_t bufsize; /* buffer size */ - size_t buflen; /* used length */ - char *buf; /* buffer */ -} POOL_INTERNAL_BUFFER; + size_t bufsize; /* buffer size */ + size_t buflen; /* used length */ + char *buf; /* buffer */ +} POOL_INTERNAL_BUFFER; /* * Temporary query cache buffer */ typedef struct { - bool is_exceeded; /* true if data size exceeds memqcache_maxcache */ - bool is_discarded; /* true if this cache entry is discarded */ - char *query; /* SELECT query */ + bool is_exceeded; /* true if data size exceeds + * memqcache_maxcache */ + bool is_discarded; /* true if this cache entry is discarded */ + char *query; /* SELECT query */ POOL_INTERNAL_BUFFER *buffer; - int num_oids; + int num_oids; POOL_INTERNAL_BUFFER *oids; -} POOL_TEMP_QUERY_CACHE; +} POOL_TEMP_QUERY_CACHE; /* * Temporary query cache buffer array */ typedef struct { - int num_caches; - int array_size; + int num_caches; + int array_size; POOL_TEMP_QUERY_CACHE *caches[1]; /* actual data continues... */ -} POOL_QUERY_CACHE_ARRAY; +} POOL_QUERY_CACHE_ARRAY; /* * Query cache statistics structure. This area must be placed on shared @@ -169,22 +177,26 @@ typedef struct { time_t start_time; /* start time when the statistics begins */ long long int num_selects; /* number of successful SELECTs */ - long long int num_cache_hits; /* number of SELECTs extracted from cache */ -} POOL_QUERY_CACHE_STATS; + long long int num_cache_hits; /* number of SELECTs extracted from cache */ +} POOL_QUERY_CACHE_STATS; /* * Shared memory cache stats interface. */ typedef struct { - int num_hash_entries; /* number of total hash entries */ - int used_hash_entries; /* number of used hash entries */ - int num_cache_entries; /* number of used cache entries */ - long used_cache_entries_size; /* total size of used cache entries */ - long free_cache_entries_size; /* total size of free(usable) cache entries */ - long fragment_cache_entries_size; /* total size of fragment(unusable) cache entries */ + int num_hash_entries; /* number of total hash entries */ + int used_hash_entries; /* number of used hash entries */ + int num_cache_entries; /* number of used cache entries */ + long used_cache_entries_size; /* total size of used cache + * entries */ + long free_cache_entries_size; /* total size of free(usable) + * cache entries */ + long fragment_cache_entries_size; /* total size of + * fragment(unusable) cache + * entries */ POOL_QUERY_CACHE_STATS cache_stats; -} POOL_SHMEM_STATS; +} POOL_SHMEM_STATS; /*-------------------------------------------------------------------------------- * On shared memory hash table implementation @@ -194,10 +206,10 @@ typedef struct /* Hash element */ typedef struct POOL_HASH_ELEMENT { - struct POOL_HASH_ELEMENT *next; /* link to next entry */ - POOL_QUERY_HASH hashkey; /* MD5 hash key */ - POOL_CACHEID cacheid; /* logical location of this cache element */ -} POOL_HASH_ELEMENT; + struct POOL_HASH_ELEMENT *next; /* link to next entry */ + POOL_QUERY_HASH hashkey; /* MD5 hash key */ + POOL_CACHEID cacheid; /* logical location of this cache element */ +} POOL_HASH_ELEMENT; typedef uint32 POOL_HASH_KEY; @@ -205,64 +217,64 @@ typedef uint32 POOL_HASH_KEY; typedef struct { POOL_HASH_KEY hashkey; /* hash key */ - POOL_HASH_ELEMENT *element; /* hash element */ -} POOL_HEADER_ELEMENT; + POOL_HASH_ELEMENT *element; /* hash element */ +} POOL_HEADER_ELEMENT; /* Hash header */ typedef struct { - long nhash; /* number of hash keys (power of 2) */ - uint32 mask; /* mask for hash function */ + long nhash; /* number of hash keys (power of 2) */ + uint32 mask; /* mask for hash function */ POOL_HEADER_ELEMENT elements[1]; /* actual hash elements follows */ -} POOL_HASH_HEADER; +} POOL_HASH_HEADER; -extern int pool_hash_init(int nelements); -extern POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key); -extern int pool_hash_delete(POOL_QUERY_HASH *key); +extern int pool_hash_init(int nelements); +extern POOL_CACHEID * pool_hash_search(POOL_QUERY_HASH * key); +extern int pool_hash_delete(POOL_QUERY_HASH * key); extern uint32 hash_any(unsigned char *k, int keylen); -extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, +extern POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, char *contents, bool *foundp); extern bool pool_is_likely_select(char *query); extern bool pool_is_table_in_black_list(const char *table_name); extern bool pool_is_table_in_white_list(const char *table_name); extern bool pool_is_allow_to_cache(Node *node, char *query); -extern int pool_extract_table_oids(Node *node, int **oidsp); +extern int pool_extract_table_oids(Node *node, int **oidsp); extern void pool_add_dml_table_oid(int oid); extern void pool_discard_oid_maps(void); -extern int pool_get_database_oid_from_dbname(char *dbname); +extern int pool_get_database_oid_from_dbname(char *dbname); extern void pool_discard_oid_maps_by_db(int dboid); extern bool pool_is_shmem_cache(void); extern size_t pool_shared_memory_cache_size(void); -extern int pool_init_memory_cache(size_t size); +extern int pool_init_memory_cache(size_t size); extern void pool_clear_memory_cache(void); extern size_t pool_shared_memory_fsmm_size(void); -extern int pool_init_fsmm(size_t size); +extern int pool_init_fsmm(size_t size); extern void pool_allocate_fsmm_clock_hand(void); -extern POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void); -extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array); +extern POOL_QUERY_CACHE_ARRAY * pool_create_query_cache_array(void); +extern void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY * cache_array); -extern POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query); -extern void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *node, char state); +extern POOL_TEMP_QUERY_CACHE * pool_create_temp_query_cache(char *query); +extern void pool_handle_query_cache(POOL_CONNECTION_POOL * backend, char *query, Node *node, char state); -extern int pool_init_memqcache_stats(void); -extern POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void); +extern int pool_init_memqcache_stats(void); +extern POOL_QUERY_CACHE_STATS * pool_get_memqcache_stats(void); extern void pool_reset_memqcache_stats(void); extern long long int pool_stats_count_up_num_selects(long long int num); extern long long int pool_stats_count_up_num_cache_hits(void); extern long long int pool_tmp_stats_count_up_num_selects(void); extern long long int pool_tmp_stats_get_num_selects(void); extern void pool_tmp_stats_reset_num_selects(void); -extern POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void); +extern POOL_SHMEM_STATS * pool_get_shmem_storage_stats(void); -extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); -extern POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void); -extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache); +extern POOL_TEMP_QUERY_CACHE * pool_get_current_cache(void); +extern POOL_TEMP_QUERY_CACHE * pool_get_current_cache(void); +extern void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache); extern void pool_shmem_lock(void); extern void pool_shmem_unlock(void); -#endif /* POOL_MEMQCACHE_H */ +#endif /* POOL_MEMQCACHE_H */ diff --git a/src/include/rewrite/pool_lobj.h b/src/include/rewrite/pool_lobj.h index c0de4d388..edd1373eb 100644 --- a/src/include/rewrite/pool_lobj.h +++ b/src/include/rewrite/pool_lobj.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group @@ -27,6 +27,6 @@ #define POOL_LOBJ_H #include "pool.h" -extern char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int* len); +extern char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int *len); -#endif /* POOL_LOBJ_H */ +#endif /* POOL_LOBJ_H */ diff --git a/src/include/rewrite/pool_timestamp.h b/src/include/rewrite/pool_timestamp.h index 1225c741a..e58ddfb0b 100644 --- a/src/include/rewrite/pool_timestamp.h +++ b/src/include/rewrite/pool_timestamp.h @@ -31,8 +31,8 @@ #include "parser/nodes.h" #include "context/pool_session_context.h" -extern char *rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, bool rewrite_to_params, POOL_SENT_MESSAGE *message); -extern char *bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, POOL_SENT_MESSAGE *message, const char *orig_msg, int *len); +extern char *rewrite_timestamp(POOL_CONNECTION_POOL * backend, Node *node, bool rewrite_to_params, POOL_SENT_MESSAGE * message); +extern char *bind_rewrite_timestamp(POOL_CONNECTION_POOL * backend, POOL_SENT_MESSAGE * message, const char *orig_msg, int *len); extern bool isSystemType(Node *node, const char *name); -#endif /* POOL_TIMESTAMP_H */ +#endif /* POOL_TIMESTAMP_H */ diff --git a/src/include/utils/elog.h b/src/include/utils/elog.h index 49699ae33..4acec995f 100644 --- a/src/include/utils/elog.h +++ b/src/include/utils/elog.h @@ -121,20 +121,22 @@ typedef enum /* pgpool-II extension. This is same as ERROR but sets the * do not cache connection flag before transforming to ERROR. */ -#define FRONTEND_ERROR 23 /* transformed to ERROR at errstart */ -#define FRONTEND_ONLY_ERROR 24 /* this is treated as LOG message internally - * for pgpool-II but forwarded to frontend clients - * just like normal errors followed by readyForQuery - * message - */ +#define FRONTEND_ERROR 23 /* transformed to ERROR at errstart */ +#define FRONTEND_ONLY_ERROR 24 /* this is treated as LOG message + * internally for pgpool-II but forwarded + * to frontend clients just like normal + * errors followed by readyForQuery + * message */ /* #define DEBUG DEBUG1 */ /* Backward compatibility with pre-7.3 */ -#define POOL_EXIT_NO_RESTART 0 /* child exiting with this error will not be - * restarted by pgpool main process - * but the pgpool main will remain unaffected by this */ -#define POOL_EXIT_AND_RESTART 1 /* child process exit with this error code will - * be restarted by the pgpool main */ -#define POOL_EXIT_FATAL 3 /* This exit code from child also takes down the pgpool main with it */ +#define POOL_EXIT_NO_RESTART 0 /* child exiting with this error will not + * be restarted by pgpool main process but + * the pgpool main will remain unaffected + * by this */ +#define POOL_EXIT_AND_RESTART 1 /* child process exit with this error code + * will be restarted by the pgpool main */ +#define POOL_EXIT_FATAL 3 /* This exit code from child also takes + * down the pgpool main with it */ @@ -196,7 +198,7 @@ typedef enum if (elevel_ >= ERROR && elevel_ != FRONTEND_ONLY_ERROR) \ pg_unreachable(); \ } while(0) -#endif /* HAVE__BUILTIN_CONSTANT_P */ +#endif /* HAVE__BUILTIN_CONSTANT_P */ #define ereport(elevel, rest) \ ereport_domain(elevel, TEXTDOMAIN, rest) @@ -292,7 +294,7 @@ extern int errposition(int cursorpos); #define pg_unreachable() exit(0) -extern bool getfrontendinvalid(void); +extern bool getfrontendinvalid(void); extern int geterrcode(void); extern int geterrposition(void); extern int getinternalerrposition(void); @@ -328,12 +330,12 @@ extern int getinternalerrposition(void); if (elevel_ >= ERROR && (elevel) != FRONTEND_ONLY_ERROR) \ pg_unreachable(); \ } while(0) -#endif /* HAVE__BUILTIN_CONSTANT_P */ +#endif /* HAVE__BUILTIN_CONSTANT_P */ #else /* !HAVE__VA_ARGS */ #define elog \ elog_start(__FILE__, __LINE__, PG_FUNCNAME_MACRO), \ elog_finish -#endif /* HAVE__VA_ARGS */ +#endif /* HAVE__VA_ARGS */ extern void elog_start(const char *filename, int lineno, const char *funcname); extern void @@ -434,8 +436,8 @@ extern PGDLLIMPORT sigjmp_buf *PG_exception_stack; typedef struct ErrorData { int elevel; /* error level */ - bool output_to_server; /* will report to server log? */ - bool output_to_client; /* will report to client? */ + bool output_to_server; /* will report to server log? */ + bool output_to_client; /* will report to client? */ bool show_funcname; /* true to force funcname inclusion */ bool hide_stmt; /* true to prevent STATEMENT: inclusion */ const char *filename; /* __FILE__ of ereport() call */ @@ -444,8 +446,9 @@ typedef struct ErrorData const char *domain; /* message domain */ const char *context_domain; /* message domain for context message */ int sqlerrcode; /* encoded ERRSTATE */ - bool frontend_invalid;/* true when frontend connection is not valid */ - char *pgpool_errcode; /* error code to be sent to client */ + bool frontend_invalid; /* true when frontend connection is not + * valid */ + char *pgpool_errcode; /* error code to be sent to client */ char *message; /* primary error message */ char *detail; /* detail error message */ char *detail_log; /* detail error message for server log only */ @@ -457,7 +460,7 @@ typedef struct ErrorData char *datatype_name; /* name of datatype */ char *constraint_name; /* name of constraint */ int cursorpos; /* cursor index into query string */ - int retcode; /* return code to be used in exit() code */ + int retcode; /* return code to be used in exit() code */ int internalpos; /* cursor index into internalquery */ char *internalquery; /* text of internally-generated query */ char *client_error_code; /* error code to report to client */ @@ -488,7 +491,7 @@ typedef enum PGERROR_TERSE, /* single-line error messages */ PGERROR_DEFAULT, /* recommended style */ PGERROR_VERBOSE /* all the facts, ma'am */ -} PGErrorVerbosity; +} PGErrorVerbosity; /* Log destination bitmap */ @@ -514,11 +517,11 @@ write_stderr(const char *fmt,...) the supplied arguments. */ __attribute__((format(PG_PRINTF_ATTRIBUTE, 1, 2))); -void shmem_exit(int code); -void on_exit_reset(void); -void cancel_shmem_exit(pg_on_exit_callback function, Datum arg); -void on_proc_exit(pg_on_exit_callback function, Datum arg); -void on_shmem_exit(pg_on_exit_callback function, Datum arg); -void on_system_exit(pg_on_exit_callback function, Datum arg); +void shmem_exit(int code); +void on_exit_reset(void); +void cancel_shmem_exit(pg_on_exit_callback function, Datum arg); +void on_proc_exit(pg_on_exit_callback function, Datum arg); +void on_shmem_exit(pg_on_exit_callback function, Datum arg); +void on_system_exit(pg_on_exit_callback function, Datum arg); -#endif /* ELOG_H */ +#endif /* ELOG_H */ diff --git a/src/include/utils/fe_ports.h b/src/include/utils/fe_ports.h index 259c8e2bf..0561e993f 100644 --- a/src/include/utils/fe_ports.h +++ b/src/include/utils/fe_ports.h @@ -36,37 +36,40 @@ extern char *simple_prompt(const char *prompt, int maxlen, bool echo); -extern int _fe_error_level; +extern int _fe_error_level; -void *pg_malloc(size_t size); +void *pg_malloc(size_t size); -void *pg_malloc0(size_t size); -void *pg_realloc(void *ptr, size_t size); -char *pg_strdup(const char *in); -void pg_free(void *ptr); -void *palloc(unsigned int size); -void *palloc0(unsigned int size); -void pfree(void *pointer); -char *pstrdup(const char *in); -void *repalloc(void *pointer, unsigned int size); +void *pg_malloc0(size_t size); +void *pg_realloc(void *ptr, size_t size); +char *pg_strdup(const char *in); +void pg_free(void *ptr); +void *palloc(unsigned int size); +void *palloc0(unsigned int size); +void pfree(void *pointer); +char *pstrdup(const char *in); +void *repalloc(void *pointer, unsigned int size); #ifdef __GNUC__ -extern int errhint(const char *fmt,...) -__attribute__((format (printf, 1, 2))); +extern int +errhint(const char *fmt,...) +__attribute__((format(printf, 1, 2))); -extern int errdetail(const char *fmt,...) -__attribute__((format (printf, 1, 2))); +extern int +errdetail(const char *fmt,...) +__attribute__((format(printf, 1, 2))); -extern void errmsg(const char *fmt,...) -__attribute__((format (printf, 1, 2))); +extern void +errmsg(const char *fmt,...) +__attribute__((format(printf, 1, 2))); #else -extern int errhint(const char *fmt,...); -extern int errdetail(const char *fmt,...); +extern int errhint(const char *fmt,...); +extern int errdetail(const char *fmt,...); extern void errmsg(const char *fmt,...); #endif extern int errstart(int elevel, const char *filename, int lineno, - const char *funcname); + const char *funcname); extern void errfinish(int dummy,...); /* @@ -96,10 +99,12 @@ extern void errfinish(int dummy,...); * WARNING is for unexpected messages. */ #define ERROR 20 /* user error - abort transaction; return to * known state */ - /* Save ERROR value in PGERROR so it can be restored when Win32 includes - * modify it. We have to use a constant rather than ERROR because macros - * are expanded only when referenced outside macros. - */ + + /* + * Save ERROR value in PGERROR so it can be restored when Win32 includes + * modify it. We have to use a constant rather than ERROR because macros are + * expanded only when referenced outside macros. + */ #ifdef WIN32 #define PGERROR 20 @@ -108,11 +113,11 @@ extern void errfinish(int dummy,...); #define PANIC 22 /* take down the other backends with me */ #define FRONTEND_ERROR 23 /* transformed to ERROR at errstart */ -#define FRONTEND_ONLY_ERROR 24 /* this is treated as LOG message internally - * for pgpool-II but forwarded to frontend clients - * just like normal errors followed by readyForQuery - * message - */ +#define FRONTEND_ONLY_ERROR 24 /* this is treated as LOG message + * internally for pgpool-II but forwarded + * to frontend clients just like normal + * errors followed by readyForQuery + * message */ #define ereport(elevel, rest) \ do { \ @@ -130,6 +135,6 @@ typedef enum PGERROR_TERSE, /* single-line error messages */ PGERROR_DEFAULT, /* recommended style */ PGERROR_VERBOSE /* all the facts, ma'am */ -} PGErrorVerbosity; +} PGErrorVerbosity; -#endif /* FE_PORTS */ +#endif /* FE_PORTS */ diff --git a/src/include/utils/getopt_long.h b/src/include/utils/getopt_long.h index 4ec1febbb..dd5d123e2 100644 --- a/src/include/utils/getopt_long.h +++ b/src/include/utils/getopt_long.h @@ -38,7 +38,7 @@ struct option extern int getopt_long(int argc, char *const argv[], const char *optstring, - const struct option * longopts, int *longindex); + const struct option *longopts, int *longindex); #endif -#endif /* GETOPT_LONG_H */ +#endif /* GETOPT_LONG_H */ diff --git a/src/include/utils/json.h b/src/include/utils/json.h index fe7bb96e1..67cc0255a 100644 --- a/src/include/utils/json.h +++ b/src/include/utils/json.h @@ -54,16 +54,16 @@ #define _JSON_H #ifndef json_char - #define json_char char +#define json_char char #endif #ifndef json_int_t - #ifndef _MSC_VER - #include <inttypes.h> - #define json_int_t int64_t - #else - #define json_int_t __int64 - #endif +#ifndef _MSC_VER +#include <inttypes.h> +#define json_int_t int64_t +#else +#define json_int_t __int64 +#endif #endif #include <stdlib.h> @@ -71,243 +71,250 @@ #ifdef __cplusplus - #include <string.h> +#include <string.h> - extern "C" - { +extern "C" +{ #endif -typedef struct -{ - unsigned long max_memory; - int settings; + typedef struct + { + unsigned long max_memory; + int settings; - /* Custom allocator support (leave null to use malloc/free) - */ + /* + * Custom allocator support (leave null to use malloc/free) + */ - void * (* mem_alloc) (size_t, int zero, void * user_data); - void (* mem_free) (void *, void * user_data); + void *(*mem_alloc) (size_t, int zero, void *user_data); + void (*mem_free) (void *, void *user_data); - void * user_data; /* will be passed to mem_alloc and mem_free */ + void *user_data; /* will be passed to mem_alloc and mem_free */ - size_t value_extra; /* how much extra space to allocate for values? */ + size_t value_extra; /* how much extra space to allocate for + * values? */ -} json_settings; + } json_settings; #define json_enable_comments 0x01 -typedef enum -{ - json_none, - json_object, - json_array, - json_integer, - json_double, - json_string, - json_boolean, - json_null - -} json_type; - -extern const struct _json_value json_value_none; - -typedef struct _json_object_entry -{ - json_char * name; - unsigned int name_length; - - struct _json_value * value; - -} json_object_entry; - -typedef struct _json_value -{ - struct _json_value * parent; - - json_type type; - - union - { - int boolean; - json_int_t integer; - double dbl; - - struct - { - unsigned int length; - json_char * ptr; /* null terminated */ - - } string; - - struct - { - unsigned int length; - - json_object_entry * values; + typedef enum + { + json_none, + json_object, + json_array, + json_integer, + json_double, + json_string, + json_boolean, + json_null - #if defined(__cplusplus) && __cplusplus >= 201103L - decltype(values) begin () const - { return values; - } - decltype(values) end () const - { return values + length; - } - #endif + } json_type; - } object; + extern const struct _json_value json_value_none; - struct - { - unsigned int length; - struct _json_value ** values; + typedef struct _json_object_entry + { + json_char *name; + unsigned int name_length; - #if defined(__cplusplus) && __cplusplus >= 201103L - decltype(values) begin () const - { return values; - } - decltype(values) end () const - { return values + length; - } - #endif + struct _json_value *value; - } array; + } json_object_entry; - } u; + typedef struct _json_value + { + struct _json_value *parent; - union - { - struct _json_value * next_alloc; - void * object_mem; + json_type type; - } _reserved; + union + { + int boolean; + json_int_t integer; + double dbl; - #ifdef JSON_TRACK_SOURCE + struct + { + unsigned int length; + json_char *ptr; /* null terminated */ - /* Location of the value in the source JSON - */ - unsigned int line, col; + } string; - #endif + struct + { + unsigned int length; + json_object_entry *values; - /* Some C++ operator sugar */ - - #ifdef __cplusplus - - public: - - inline _json_value () - { memset (this, 0, sizeof (_json_value)); - } - - inline const struct _json_value &operator [] (int index) const - { - if (type != json_array || index < 0 - || ((unsigned int) index) >= u.array.length) - { - return json_value_none; - } - - return *u.array.values [index]; - } +#if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin() const + { + return values; + } + decltype(values) end() const + { + return values + length; + } +#endif - inline const struct _json_value &operator [] (const char * index) const - { - if (type != json_object) - return json_value_none; + } object; + + struct + { + unsigned int length; + struct _json_value **values; + +#if defined(__cplusplus) && __cplusplus >= 201103L + decltype(values) begin() const + { + return values; + } + decltype(values) end() const + { + return values + length; + } +#endif - for (unsigned int i = 0; i < u.object.length; ++ i) - if (!strcmp (u.object.values [i].name, index)) - return *u.object.values [i].value; + } array; - return json_value_none; - } + } u; - inline operator const char * () const - { - switch (type) - { - case json_string: - return u.string.ptr; + union + { + struct _json_value *next_alloc; + void *object_mem; - default: - return ""; - }; - } + } _reserved; - inline operator json_int_t () const - { - switch (type) - { - case json_integer: - return u.integer; +#ifdef JSON_TRACK_SOURCE - case json_double: - return (json_int_t) u.dbl; + /* + * Location of the value in the source JSON + */ + unsigned int line, + col; - default: - return 0; - }; - } +#endif - inline operator bool () const - { - if (type != json_boolean) - return false; - return u.boolean != 0; - } + /* Some C++ operator sugar */ - inline operator double () const - { - switch (type) - { - case json_integer: - return (double) u.integer; +#ifdef __cplusplus - case json_double: - return u.dbl; + public: + + inline _json_value() + { + memset(this, 0, sizeof(_json_value)); + } + + inline const struct _json_value &operator[] (int index) const + { + if (type != json_array || index < 0 + || ((unsigned int) index) >= u.array.length) + { + return json_value_none; + } + + return *u.array.values[index]; + } + + inline const struct _json_value &operator[] (const char *index) const + { + if (type != json_object) + return json_value_none; + + for (unsigned int i = 0; i < u.object.length; ++i) + if (!strcmp(u.object.values[i].name, index)) + return *u.object.values[i].value; + + return json_value_none; + } + + inline operator const char *() const + { + switch (type) + { + case json_string: + return u.string.ptr; + + default: + return ""; + }; + } + + inline operator json_int_t() const + { + switch (type) + { + case json_integer: + return u.integer; + + case json_double: + return (json_int_t) u.dbl; + + default: + return 0; + }; + } + + inline operator bool () const + { + if (type != json_boolean) + return false; + + return u.boolean != 0; + } + + inline operator double () const + { + switch (type) + { + case json_integer: + return (double) u.integer; + + case json_double: + return u.dbl; + + default: + return 0; + }; + } - default: - return 0; - }; - } +#endif - #endif + } json_value; -} json_value; - -json_value * json_parse (const json_char * json, - size_t length); + json_value *json_parse(const json_char * json, + size_t length); #define json_error_max 128 -json_value * json_parse_ex (json_settings * settings, - const json_char * json, - size_t length, - char * error); + json_value *json_parse_ex(json_settings * settings, + const json_char * json, + size_t length, + char *error); -void json_value_free (json_value *); + void json_value_free(json_value *); /* Not usually necessary, unless you used a custom mem_alloc and now want to * use a custom mem_free. */ -void json_value_free_ex (json_settings * settings, - json_value *); + void json_value_free_ex(json_settings * settings, + json_value *); #ifdef __cplusplus - } /* extern "C" */ +} /* 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); +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 47e3947cf..87bca0d0d 100644 --- a/src/include/utils/json_writer.h +++ b/src/include/utils/json_writer.h @@ -28,41 +28,42 @@ typedef enum JWElementType { JWOBJECT, JWARRAY -}JWElementType; +} JWElementType; typedef struct JWStack { JWElementType elementType; - int elementCount; -}JWStack; + int elementCount; +} JWStack; -typedef struct JsonNode{ - StringInfo buf; - bool pretty; - int stack_ptr; - JWStack stack[MAX_STACK_DEPTH]; -}JsonNode; +typedef struct JsonNode +{ + StringInfo buf; + bool pretty; + int stack_ptr; + JWStack stack[MAX_STACK_DEPTH]; +} JsonNode; -extern JsonNode* jw_create(JWElementType rootElement, bool pretty_output); -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); -extern bool jw_start_array(JsonNode* jNode, char* key); -extern bool jw_start_object(JsonNode* jNode, char* key); -extern bool jw_end_element(JsonNode* jNode); -extern bool jw_finish_document(JsonNode* jNode); -extern char* jw_get_json_string(JsonNode* jNode); -extern int jw_get_json_length(JsonNode* jNode); -extern void jw_destroy(JsonNode* jNode); +extern JsonNode * jw_create(JWElementType rootElement, bool pretty_output); +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); +extern bool jw_start_array(JsonNode * jNode, char *key); +extern bool jw_start_object(JsonNode * jNode, char *key); +extern bool jw_end_element(JsonNode * jNode); +extern bool jw_finish_document(JsonNode * jNode); +extern char *jw_get_json_string(JsonNode * jNode); +extern int jw_get_json_length(JsonNode * jNode); +extern void jw_destroy(JsonNode * jNode); #endif diff --git a/src/include/utils/memdebug.h b/src/include/utils/memdebug.h index 0b955693e..d258935ff 100644 --- a/src/include/utils/memdebug.h +++ b/src/include/utils/memdebug.h @@ -31,4 +31,4 @@ #define VALGRIND_MEMPOOL_CHANGE(context, optr, nptr, size) do {} while (0) #endif -#endif /* MEMDEBUG_H */ +#endif /* MEMDEBUG_H */ diff --git a/src/include/utils/pool_ip.h b/src/include/utils/pool_ip.h index 94fa21001..b43c2ecb3 100644 --- a/src/include/utils/pool_ip.h +++ b/src/include/utils/pool_ip.h @@ -6,7 +6,7 @@ * This file was imported from PostgreSQL 8.0.8 source code. * See below for the copyright and description. * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008 PgPool Global Development Group @@ -32,37 +32,37 @@ #include "pool_type.h" -extern int SockAddr_cidr_mask(struct sockaddr_storage * mask, - char *numbits, int family); +extern int SockAddr_cidr_mask(struct sockaddr_storage *mask, + char *numbits, int family); typedef void (*PgIfAddrCallback) (struct sockaddr *addr, struct sockaddr *netmask, void *cb_data); extern int getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo * hintp, - struct addrinfo ** result); -extern void freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai); + const struct addrinfo *hintp, + struct addrinfo **result); +extern void freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai); -extern int getnameinfo_all(const struct sockaddr_storage * addr, int salen, +extern int getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags); -extern int rangeSockAddr(const struct sockaddr_storage * addr, - const struct sockaddr_storage * netaddr, - const struct sockaddr_storage * netmask); +extern int rangeSockAddr(const struct sockaddr_storage *addr, + const struct sockaddr_storage *netaddr, + const struct sockaddr_storage *netmask); /* imported from PostgreSQL getaddrinfo.c */ #ifndef HAVE_GAI_STRERROR -extern const char * gai_strerror(int errcode); -#endif /* HAVE_GAI_STRERROR */ +extern const char *gai_strerror(int errcode); +#endif /* HAVE_GAI_STRERROR */ -extern void promote_v4_to_v6_addr(struct sockaddr_storage * addr); -extern void promote_v4_to_v6_mask(struct sockaddr_storage * addr); +extern void promote_v4_to_v6_addr(struct sockaddr_storage *addr); +extern void promote_v4_to_v6_mask(struct sockaddr_storage *addr); -extern int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data); +extern int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data); #define IS_AF_INET(fam) ((fam) == AF_INET) #define IS_AF_UNIX(fam) ((fam) == AF_UNIX) -#endif /* IP_H */ +#endif /* IP_H */ diff --git a/src/include/utils/pool_ipc.h b/src/include/utils/pool_ipc.h index 7571a3910..c65de05b5 100644 --- a/src/include/utils/pool_ipc.h +++ b/src/include/utils/pool_ipc.h @@ -2,7 +2,7 @@ /* * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008, PgPool Global Development Group @@ -29,4 +29,4 @@ extern void shmem_exit(int code); extern void on_shmem_exit(void (*function) (int code, Datum arg), Datum arg); extern void on_exit_reset(void); -#endif /* IPC_H */ +#endif /* IPC_H */ diff --git a/src/include/utils/pool_path.h b/src/include/utils/pool_path.h index e40830c74..f0bb4c2b9 100644 --- a/src/include/utils/pool_path.h +++ b/src/include/utils/pool_path.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2015, PgPool Global Development Group @@ -52,6 +52,6 @@ extern char *last_dir_separator(const char *filename); extern bool get_home_directory(char *buf, int bufsize); extern bool get_os_username(char *buf, int bufsize); extern char *get_current_working_dir(void); -extern char *make_absolute_path(const char *path, const char* base_dir); +extern char *make_absolute_path(const char *path, const char *base_dir); -#endif /* POOL_PATH_H */ +#endif /* POOL_PATH_H */ diff --git a/src/include/utils/pool_process_reporting.h b/src/include/utils/pool_process_reporting.h index 08af51d8e..eb75f3def 100644 --- a/src/include/utils/pool_process_reporting.h +++ b/src/include/utils/pool_process_reporting.h @@ -26,22 +26,22 @@ #ifndef POOL_PROCESS_REPORTING_H #define POOL_PROCESS_REPORTING_H -extern void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - short num_fields, char **field_names); -extern void send_complete_and_ready(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* message, const int num_rows); -extern POOL_REPORT_CONFIG* get_config(int *nrows); -extern POOL_REPORT_POOLS* get_pools(int *nrows); -extern POOL_REPORT_PROCESSES* get_processes(int *nrows); -extern POOL_REPORT_NODES* get_nodes(int *nrows); -extern POOL_REPORT_VERSION* get_version(void); -extern void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); -extern void cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern void send_row_description(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + short num_fields, char **field_names); +extern void send_complete_and_ready(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *message, const int num_rows); +extern POOL_REPORT_CONFIG * get_config(int *nrows); +extern POOL_REPORT_POOLS * get_pools(int *nrows); +extern POOL_REPORT_PROCESSES * get_processes(int *nrows); +extern POOL_REPORT_NODES * get_nodes(int *nrows); +extern POOL_REPORT_VERSION * get_version(void); +extern void config_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void pools_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void processes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void nodes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void version_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); +extern void cache_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); -extern void send_config_var_detail_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* name, const char* value, const char* description); -extern void send_config_var_value_only_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* value); -extern char* get_backend_status_string(BACKEND_STATUS status); +extern void send_config_var_detail_row(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value, const char *description); +extern void send_config_var_value_only_row(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *value); +extern char *get_backend_status_string(BACKEND_STATUS status); #endif diff --git a/src/include/utils/pool_relcache.h b/src/include/utils/pool_relcache.h index c7510f429..6b090523a 100644 --- a/src/include/utils/pool_relcache.h +++ b/src/include/utils/pool_relcache.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group @@ -36,44 +36,49 @@ typedef void *(*func_ptr) (); -typedef struct { - char dbname[MAX_ITEM_LENGTH]; /* database name */ - char relname[MAX_ITEM_LENGTH]; /* table name */ - void *data; /* user data */ - int refcnt; /* reference count */ - int session_id; /* LocalSessionId */ - time_t expire; /* cache expiration absolute time in seconds */ -} PoolRelCache; +typedef struct +{ + char dbname[MAX_ITEM_LENGTH]; /* database name */ + char relname[MAX_ITEM_LENGTH]; /* table name */ + void *data; /* user data */ + int refcnt; /* reference count */ + int session_id; /* LocalSessionId */ + time_t expire; /* cache expiration absolute time in seconds */ +} PoolRelCache; + +typedef struct +{ + int num; /* number of cache items */ + char sql[MAX_ITEM_LENGTH]; /* Query to relation */ -typedef struct { - int num; /* number of cache items */ - char sql[MAX_ITEM_LENGTH]; /* Query to relation */ /* - * User defined function to be called at data register. - * Argument is POOL_SELECT_RESULT *. - * This function must return a pointer to be - * saved in cache->data. + * User defined function to be called at data register. Argument is + * POOL_SELECT_RESULT *. This function must return a pointer to be saved + * in cache->data. */ func_ptr register_func; + /* - * User defined function to be called at data unregister. - * Argument cache->data. + * User defined function to be called at data unregister. Argument + * cache->data. */ func_ptr unregister_func; - bool cache_is_session_local; /* True if cache life time is session local */ - bool no_cache_if_zero; /* if register func returns 0, do not cache the data */ - PoolRelCache *cache; /* cache data */ -} POOL_RELCACHE; + bool cache_is_session_local; /* True if cache life time is session + * local */ + bool no_cache_if_zero; /* if register func returns 0, do not + * cache the data */ + PoolRelCache *cache; /* cache data */ +} POOL_RELCACHE; -extern POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, - func_ptr register_func, func_ptr unregister_func, - bool issessionlocal); -extern void pool_discard_relcache(POOL_RELCACHE *relcache); -extern void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table); +extern POOL_RELCACHE * pool_create_relcache(int cachesize, char *sql, + func_ptr register_func, func_ptr unregister_func, + bool issessionlocal); +extern void pool_discard_relcache(POOL_RELCACHE * relcache); +extern void *pool_search_relcache(POOL_RELCACHE * relcache, POOL_CONNECTION_POOL * backend, char *table); extern char *remove_quotes_and_schema_from_relname(char *table); -extern void *int_register_func(POOL_SELECT_RESULT *res); +extern void *int_register_func(POOL_SELECT_RESULT * res); extern void *int_unregister_func(void *data); -extern void *string_register_func(POOL_SELECT_RESULT *res); +extern void *string_register_func(POOL_SELECT_RESULT * res); extern void *string_unregister_func(void *data); -#endif /* POOL_RELCACHE_H */ +#endif /* POOL_RELCACHE_H */ diff --git a/src/include/utils/pool_select_walker.h b/src/include/utils/pool_select_walker.h index 4195aa6f1..10323b08f 100644 --- a/src/include/utils/pool_select_walker.h +++ b/src/include/utils/pool_select_walker.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2012 PgPool Global Development Group @@ -32,23 +32,29 @@ #include "parser/makefuncs.h" #define POOL_MAX_SELECT_OIDS 128 -#define POOL_NAMEDATALEN 64 /* from NAMEDATALEN of PostgreSQL */ +#define POOL_NAMEDATALEN 64 /* from NAMEDATALEN of PostgreSQL */ -typedef struct { - bool has_system_catalog; /* True if system catalog table is used */ - bool has_temp_table; /* True if temporary table is used */ - bool has_unlogged_table; /* True if unlogged table is used */ - bool has_view; /* True if view is used */ - bool has_function_call; /* True if write function call is used */ - int pg_terminate_backend_pid; /* pid argument of pg_terminate_backedn_call(if used) */ - bool has_non_immutable_function_call; /* True if non immutable functions are used */ - bool has_insertinto_or_locking_clause; /* True if it has SELECT INTO or FOR SHARE/UPDATE */ - int num_oids; /* number of oids */ - int table_oids[POOL_MAX_SELECT_OIDS]; /* table oids */ - char table_names[POOL_MAX_SELECT_OIDS][POOL_NAMEDATALEN]; /* table names */ -} SelectContext; +typedef struct +{ + bool has_system_catalog; /* True if system catalog table is used */ + bool has_temp_table; /* True if temporary table is used */ + bool has_unlogged_table; /* True if unlogged table is used */ + bool has_view; /* True if view is used */ + bool has_function_call; /* True if write function call is used */ + int pg_terminate_backend_pid; /* pid argument of + * pg_terminate_backedn_call(if + * used) */ + bool has_non_immutable_function_call; /* True if non immutable + * functions are used */ + bool has_insertinto_or_locking_clause; /* True if it has SELECT + * INTO or FOR + * SHARE/UPDATE */ + int num_oids; /* number of oids */ + int table_oids[POOL_MAX_SELECT_OIDS]; /* table oids */ + char table_names[POOL_MAX_SELECT_OIDS][POOL_NAMEDATALEN]; /* table names */ +} SelectContext; -extern int pool_get_terminate_backend_pid(Node *node); +extern int pool_get_terminate_backend_pid(Node *node); extern bool pool_has_function_call(Node *node); extern bool pool_has_non_immutable_function_call(Node *node); extern bool pool_has_system_catalog(Node *node); @@ -60,12 +66,12 @@ extern bool pool_has_insertinto_or_locking_clause(Node *node); extern bool pool_has_pgpool_regclass(void); extern bool pool_has_to_regclass(void); extern bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context); -extern int pool_table_name_to_oid(char *table_name); -extern int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext *ctx); +extern int pool_table_name_to_oid(char *table_name); +extern int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext * ctx); extern RangeVar *makeRangeVarFromNameList(List *names); extern char *make_table_name_from_rangevar(RangeVar *rangevar); -extern int pattern_compare(char *str, const int type, const char *param_name); +extern int pattern_compare(char *str, const int type, const char *param_name); extern bool is_unlogged_table(char *table_name); extern bool is_view(char *table_name); -#endif /* POOL_SELECT_WALKER_H */ +#endif /* POOL_SELECT_WALKER_H */ diff --git a/src/include/utils/pool_signal.h b/src/include/utils/pool_signal.h index 3c29d04c1..012f3d1ce 100644 --- a/src/include/utils/pool_signal.h +++ b/src/include/utils/pool_signal.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Portions Copyright (c) 2003-2008, PgPool Global Development Group @@ -66,5 +66,5 @@ int pqsigsetmask(int mask); typedef void (*pool_sighandler_t) (int); extern pool_sighandler_t pool_signal(int signo, pool_sighandler_t func); extern void poolinitmask(void); -extern int pool_signal_parent(int sig); -#endif /* POOL_SIGNAL_H */ +extern int pool_signal_parent(int sig); +#endif /* POOL_SIGNAL_H */ diff --git a/src/include/utils/pool_stream.h b/src/include/utils/pool_stream.h index c79f5dfbe..6206543cc 100644 --- a/src/include/utils/pool_stream.h +++ b/src/include/utils/pool_stream.h @@ -3,7 +3,7 @@ * * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2015 PgPool Global Development Group @@ -42,31 +42,31 @@ (connection)->len = 0; \ } while (0) -extern POOL_CONNECTION *pool_open(int fd, bool backend_connection); -extern void pool_close(POOL_CONNECTION *cp); -extern int pool_read(POOL_CONNECTION *cp, void *buf, int len); -extern void pool_read_with_error(POOL_CONNECTION *cp, void *buf, int len, - const char* err_context ); +extern POOL_CONNECTION * pool_open(int fd, bool backend_connection); +extern void pool_close(POOL_CONNECTION * cp); +extern int pool_read(POOL_CONNECTION * cp, void *buf, int len); +extern void pool_read_with_error(POOL_CONNECTION * cp, void *buf, int len, + const char *err_context); -extern char *pool_read2(POOL_CONNECTION *cp, int len); -extern int pool_write(POOL_CONNECTION *cp, void *buf, int len); -extern int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len); -extern int pool_flush(POOL_CONNECTION *cp); -extern int pool_flush_noerror(POOL_CONNECTION *cp); -extern int pool_flush_it(POOL_CONNECTION *cp); -extern void pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len); -extern int pool_write_and_flush_noerror(POOL_CONNECTION *cp, void *buf, int len); -extern char *pool_read_string(POOL_CONNECTION *cp, int *len, int line); -extern int pool_unread(POOL_CONNECTION *cp, void *data, int len); -extern int pool_push(POOL_CONNECTION *cp, void *data, int len); -extern void pool_pop(POOL_CONNECTION *cp, int *len); -extern int pool_stacklen(POOL_CONNECTION *cp); +extern char *pool_read2(POOL_CONNECTION * cp, int len); +extern int pool_write(POOL_CONNECTION * cp, void *buf, int len); +extern int pool_write_noerror(POOL_CONNECTION * cp, void *buf, int len); +extern int pool_flush(POOL_CONNECTION * cp); +extern int pool_flush_noerror(POOL_CONNECTION * cp); +extern int pool_flush_it(POOL_CONNECTION * cp); +extern void pool_write_and_flush(POOL_CONNECTION * cp, void *buf, int len); +extern int pool_write_and_flush_noerror(POOL_CONNECTION * cp, void *buf, int len); +extern char *pool_read_string(POOL_CONNECTION * cp, int *len, int line); +extern int pool_unread(POOL_CONNECTION * cp, void *data, int len); +extern int pool_push(POOL_CONNECTION * cp, void *data, int len); +extern void pool_pop(POOL_CONNECTION * cp, int *len); +extern int pool_stacklen(POOL_CONNECTION * cp); extern void pool_set_nonblock(int fd); extern void pool_unset_nonblock(int fd); -extern int socket_read(int sock, void* buf, size_t len, int timeout); -extern int socket_write(int fd, void* buf, size_t len); +extern int socket_read(int sock, void *buf, size_t len, int timeout); +extern int socket_write(int fd, void *buf, size_t len); -extern void pool_set_db_node_id(POOL_CONNECTION *con, int db_node_id); +extern void pool_set_db_node_id(POOL_CONNECTION * con, int db_node_id); -#endif /* POOL_STREAM_H */ +#endif /* POOL_STREAM_H */ diff --git a/src/include/utils/regex_array.h b/src/include/utils/regex_array.h index 3596ca608..a50d1ea29 100644 --- a/src/include/utils/regex_array.h +++ b/src/include/utils/regex_array.h @@ -1,7 +1,7 @@ /* -*-pgsql-c-*- */ /* * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2014 PgPool Global Development Group @@ -29,33 +29,36 @@ /* * Regular expression array */ -typedef struct { - int size; /* regex array size */ - int pos; /* next regex array index position */ - regex_t **regex; /* regular expression array */ -} RegArray; +typedef struct +{ + int size; /* regex array size */ + int pos; /* next regex array index position */ + regex_t **regex; /* regular expression array */ +} RegArray; -RegArray *create_regex_array(void); -int add_regex_array(RegArray *ar, char *pattern); -int regex_array_match(RegArray *ar, char *pattern); -void destroy_regex_arrary(RegArray *ar); +RegArray *create_regex_array(void); +int add_regex_array(RegArray * ar, char *pattern); +int regex_array_match(RegArray * ar, char *pattern); +void destroy_regex_arrary(RegArray * ar); /* * String left-right token type */ -typedef struct { - char *left_token; - char *right_token; - double weight_token; -} Left_right_token; - -typedef struct { - int pos; - int size; - Left_right_token *token; -} Left_right_tokens; +typedef struct +{ + char *left_token; + char *right_token; + double weight_token; +} Left_right_token; + +typedef struct +{ + int pos; + int size; + Left_right_token *token; +} Left_right_tokens; Left_right_tokens *create_lrtoken_array(void); -void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_tokens *lrtokens); +void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_tokens * lrtokens); #endif diff --git a/src/include/utils/ssl_utils.h b/src/include/utils/ssl_utils.h index 36b053d40..e6aabcac7 100644 --- a/src/include/utils/ssl_utils.h +++ b/src/include/utils/ssl_utils.h @@ -27,8 +27,8 @@ extern void calculate_hmac_sha256(const char *data, int len, char *buf); extern int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, - const char *password, unsigned char *plaintext); + const char *password, unsigned char *plaintext); extern int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, - const char *password, unsigned char *ciphertext); + const char *password, unsigned char *ciphertext); #endif diff --git a/src/include/watchdog/watchdog.h b/src/include/watchdog/watchdog.h index f7753b788..36f384116 100644 --- a/src/include/watchdog/watchdog.h +++ b/src/include/watchdog/watchdog.h @@ -40,7 +40,8 @@ /* * watchdog state */ -typedef enum { +typedef enum +{ WD_DEAD = 0, WD_LOADING, WD_JOINING, @@ -55,24 +56,26 @@ typedef enum { /* the following states are only valid on remote nodes */ WD_SHUTDOWN, WD_ADD_MESSAGE_SENT -} WD_STATES; +} WD_STATES; -typedef enum { +typedef enum +{ WD_SOCK_UNINITIALIZED = 0, WD_SOCK_CREATED, WD_SOCK_WAITING_FOR_CONNECT, WD_SOCK_CONNECTED, WD_SOCK_ERROR, WD_SOCK_CLOSED -} WD_SOCK_STATE; +} WD_SOCK_STATE; -typedef enum { +typedef enum +{ WD_EVENT_WD_STATE_CHANGED = 0, WD_EVENT_TIMEOUT, WD_EVENT_PACKET_RCV, WD_EVENT_COMMAND_FINISHED, WD_EVENT_NEW_OUTBOUND_CONNECTION, - + WD_EVENT_NW_IP_IS_REMOVED, WD_EVENT_NW_IP_IS_ASSIGNED, @@ -88,48 +91,47 @@ typedef enum { WD_EVENT_NODE_CON_FOUND, WD_EVENT_CLUSTER_QUORUM_CHANGED -} WD_EVENTS; +} WD_EVENTS; typedef struct SocketConnection { - int sock; /* socket descriptor */ - struct timeval tv; /* connect time of socket */ - char addr[48]; /* ip address of socket connection*/ - WD_SOCK_STATE sock_state; /* current state of socket */ -}SocketConnection; + int sock; /* socket descriptor */ + struct timeval tv; /* connect time of socket */ + char addr[48]; /* ip address of socket connection */ + WD_SOCK_STATE sock_state; /* current state of socket */ +} SocketConnection; typedef struct WatchdogNode { - WD_STATES state; - struct timeval current_state_time; /* time value when the node state last changed*/ - struct timeval startup_time; /* startup time value of node */ - struct timeval last_rcv_time; /* timestamp when last packet - * was received from the node - */ - struct timeval last_sent_time; /* timestamp when last packet - * was sent on the node - */ - char nodeName[WD_MAX_HOST_NAMELEN]; /* name of this node */ - char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ - int wd_port; /* watchdog port */ - int pgpool_port; /* pgpool port */ - int wd_priority; /* watchdog priority */ - char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ - int private_id; /* ID assigned to this node - * This id is consumed locally - */ - int standby_nodes_count; /* number of standby nodes joined the cluster - * only applicable when this WatchdogNode is - * the master/coordinator node*/ - int quorum_status; /* quorum status on the node */ - bool escalated; /* true if the Watchdog node has - * performed escalation */ - SocketConnection server_socket; /* socket connections for this node initiated by remote */ - SocketConnection client_socket; /* socket connections for this node initiated by local*/ -}WatchdogNode; + WD_STATES state; + struct timeval current_state_time; /* time value when the node state last + * changed */ + struct timeval startup_time; /* startup time value of node */ + struct timeval last_rcv_time; /* timestamp when last packet was received + * from the node */ + struct timeval last_sent_time; /* timestamp when last packet was sent on + * the node */ + char nodeName[WD_MAX_HOST_NAMELEN]; /* name of this node */ + char hostname[WD_MAX_HOST_NAMELEN]; /* host name */ + int wd_port; /* watchdog port */ + int pgpool_port; /* pgpool port */ + int wd_priority; /* watchdog priority */ + char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ + int private_id; /* ID assigned to this node This id is + * consumed locally */ + int standby_nodes_count; /* number of standby nodes joined the + * cluster only applicable when this + * WatchdogNode is the + * master/coordinator node */ + int quorum_status; /* quorum status on the node */ + bool escalated; /* true if the Watchdog node has performed + * escalation */ + SocketConnection server_socket; /* socket connections for this node + * initiated by remote */ + SocketConnection client_socket; /* socket connections for this node + * initiated by local */ +} WatchdogNode; extern pid_t initialize_watchdog(void); -#endif /* WATCHDOG_H */ - - +#endif /* WATCHDOG_H */ diff --git a/src/include/watchdog/wd_ipc_commands.h b/src/include/watchdog/wd_ipc_commands.h index dbcaa4a9d..78c78c6cd 100644 --- a/src/include/watchdog/wd_ipc_commands.h +++ b/src/include/watchdog/wd_ipc_commands.h @@ -35,32 +35,32 @@ typedef enum WdCommandResult COMMAND_OK, COMMAND_FAILED, COMMAND_TIMEOUT -}WdCommandResult; +} WdCommandResult; typedef struct WDIPCCmdResult { - char type; - int length; - char* data; -}WDIPCCmdResult; + char type; + int length; + char *data; +} WDIPCCmdResult; typedef struct WDGenericData { - WDValueDataType valueType; + WDValueDataType valueType; union data { - char *stringVal; - int intVal; - bool boolVal; - long longVal; - }data; -}WDGenericData; + char *stringVal; + int intVal; + bool boolVal; + long longVal; + } data; +} WDGenericData; extern void wd_ipc_initialize_data(void); -extern char* get_watchdog_ipc_address(void); -extern unsigned int* get_ipc_shared_key(void); +extern char *get_watchdog_ipc_address(void); +extern unsigned int *get_ipc_shared_key(void); extern void set_watchdog_process_needs_cleanup(void); extern void reset_watchdog_process_needs_cleanup(void); extern bool get_watchdog_process_needs_cleanup(void); @@ -74,14 +74,14 @@ extern WDFailoverCMDResults wd_send_failback_request(int node_id, unsigned char extern WDFailoverCMDResults wd_degenerate_backend_set(int *node_id_set, int count, unsigned char flags); extern WDFailoverCMDResults wd_promote_backend(int node_id, unsigned char flags); -extern WDPGBackendStatus* get_pg_backend_status_from_master_wd_node(void); -extern WDGenericData *get_wd_runtime_variable_value(char *varName); +extern WDPGBackendStatus * get_pg_backend_status_from_master_wd_node(void); +extern WDGenericData * get_wd_runtime_variable_value(char *varName); extern WD_STATES get_watchdog_local_node_state(void); -extern int get_watchdog_quorum_state(void); +extern int get_watchdog_quorum_state(void); -extern char* wd_get_watchdog_nodes(int nodeID); +extern char *wd_get_watchdog_nodes(int nodeID); -extern WDIPCCmdResult* issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, bool blocking); +extern WDIPCCmdResult * issue_command_to_watchdog(char type, int timeout_sec, char *data, int data_len, bool blocking); /* functions for failover commands interlocking */ @@ -90,4 +90,4 @@ extern WDFailoverCMDResults wd_failover_start(void); -#endif /* WD_IPC_COMMANDS_H */ +#endif /* WD_IPC_COMMANDS_H */ diff --git a/src/include/watchdog/wd_ipc_defines.h b/src/include/watchdog/wd_ipc_defines.h index c580b96dd..1e19e8e5b 100644 --- a/src/include/watchdog/wd_ipc_defines.h +++ b/src/include/watchdog/wd_ipc_defines.h @@ -27,12 +27,11 @@ typedef enum WDFailoverCMDResults { - FAILOVER_RES_ERROR = 0, /* processing of command is failed */ - FAILOVER_RES_TRANSITION, /* cluster is transitioning and is - * currently not accepting any commands. - * retry is the best option when this result - * is returned by watchdog - */ + FAILOVER_RES_ERROR = 0, /* processing of command is failed */ + FAILOVER_RES_TRANSITION, /* cluster is transitioning and is currently + * not accepting any commands. retry is the + * best option when this result is returned by + * watchdog */ FAILOVER_RES_SUCCESS, FAILOVER_RES_PROCEED, FAILOVER_RES_NO_QUORUM, @@ -43,7 +42,7 @@ typedef enum WDFailoverCMDResults FAILOVER_RES_BUILDING_CONSENSUS, FAILOVER_RES_CONSENSUS_MAY_FAIL, FAILOVER_RES_TIMEOUT -}WDFailoverCMDResults; +} WDFailoverCMDResults; typedef enum WDValueDataType { @@ -51,7 +50,7 @@ typedef enum WDValueDataType VALUE_DATA_TYPE_STRING, VALUE_DATA_TYPE_BOOL, VALUE_DATA_TYPE_LONG -}WDValueDataType; +} WDValueDataType; /* IPC MESSAGES TYPES */ #define WD_REGISTER_FOR_NOTIFICATION '0' @@ -91,16 +90,20 @@ typedef enum WDValueDataType #define WD_FAILOVER_ID_KEY "FAILOVER_COMMAND_ID" -#define WD_IPC_AUTH_KEY "IPCAuthKey" /* JSON data key for authentication. - * watchdog IPC server use the value for this key - * to authenticate the external IPC clients - * The valid value for this key is wd_authkey - * configuration parameter - */ -#define WD_IPC_SHARED_KEY "IPCSharedKey" /* JSON data key for authentication. - * watchdog IPC server use the value of this key - * to authenticate the internal pgpool-II processes - */ +#define WD_IPC_AUTH_KEY "IPCAuthKey" /* JSON data key for + * authentication. watchdog + * IPC server use the value + * for this key to + * authenticate the external + * IPC clients The valid value + * for this key is wd_authkey + * configuration parameter */ +#define WD_IPC_SHARED_KEY "IPCSharedKey" /* JSON data key for + * authentication. watchdog + * IPC server use the value of + * this key to authenticate + * the internal pgpool-II + * processes */ /* Watchdog runtime variable names */ diff --git a/src/include/watchdog/wd_json_data.h b/src/include/watchdog/wd_json_data.h index 648aad357..1e22ee531 100644 --- a/src/include/watchdog/wd_json_data.h +++ b/src/include/watchdog/wd_json_data.h @@ -30,16 +30,16 @@ typedef struct WDNodeInfo { - int state; - char nodeName[WD_MAX_HOST_NAMELEN]; - char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ - char stateName[WD_MAX_HOST_NAMELEN]; /* watchdog state name */ - int wd_port; /* watchdog port */ - int pgpool_port; /* pgpool port */ - int wd_priority; /* node priority */ - char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ - int id; -}WDNodeInfo; + int state; + char nodeName[WD_MAX_HOST_NAMELEN]; + char hostName[WD_MAX_HOST_NAMELEN]; /* host name */ + char stateName[WD_MAX_HOST_NAMELEN]; /* watchdog state name */ + int wd_port; /* watchdog port */ + int pgpool_port; /* pgpool port */ + int wd_priority; /* node priority */ + char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */ + int id; +} WDNodeInfo; /* * The structure to hold the parsed PG backend node status data fetched @@ -47,39 +47,40 @@ typedef struct WDNodeInfo */ typedef struct WDPGBackendStatus { - int primary_node_id; - int node_count; + int primary_node_id; + int node_count; BACKEND_STATUS backend_status[MAX_NUM_BACKENDS]; - char nodeName[WD_MAX_HOST_NAMELEN]; /* name of the watchdog node that sent the data */ -}WDPGBackendStatus; + char nodeName[WD_MAX_HOST_NAMELEN]; /* name of the watchdog node + * that sent the data */ +} WDPGBackendStatus; -extern WatchdogNode* get_watchdog_node_from_json(char* json_data, int data_len, char** authkey); -extern char* get_watchdog_node_info_json(WatchdogNode* wdNode, char* authkey); -extern POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len); -extern char* get_pool_config_json(void); -extern char* get_lifecheck_node_status_change_json(int nodeID, int nodeStatus, char* message, char* authKey); -extern bool parse_node_status_json(char* json_data, int data_len, int* nodeID, int* nodeStatus, char** message); +extern WatchdogNode * get_watchdog_node_from_json(char *json_data, int data_len, char **authkey); +extern char *get_watchdog_node_info_json(WatchdogNode * wdNode, char *authkey); +extern POOL_CONFIG * get_pool_config_from_json(char *json_data, int data_len); +extern char *get_pool_config_json(void); +extern char *get_lifecheck_node_status_change_json(int nodeID, int nodeStatus, char *message, char *authKey); +extern bool parse_node_status_json(char *json_data, int data_len, int *nodeID, int *nodeStatus, char **message); -extern WDNodeInfo* get_WDNodeInfo_from_wd_node_json(json_value* source); +extern WDNodeInfo * get_WDNodeInfo_from_wd_node_json(json_value * source); -extern bool parse_beacon_message_json(char* json_data, int data_len, int* state, - long* seconds_since_node_startup, - long* seconds_since_current_state, - int* quorumStatus, - int* standbyNodesCount, - bool* escalated); -extern char* get_beacon_message_json(WatchdogNode* wdNode); +extern bool parse_beacon_message_json(char *json_data, int data_len, int *state, + long *seconds_since_node_startup, + long *seconds_since_current_state, + int *quorumStatus, + int *standbyNodesCount, + bool *escalated); +extern char *get_beacon_message_json(WatchdogNode * wdNode); -extern char* get_wd_node_function_json(char* func_name, int *node_id_set, int count, unsigned char flags, unsigned int sharedKey, char* authKey); -extern bool parse_wd_node_function_json(char* json_data, int data_len, char** func_name, int **node_id_set, int *count, unsigned char *flags); -extern char* get_wd_simple_message_json(char* message); +extern char *get_wd_node_function_json(char *func_name, int *node_id_set, int count, unsigned char flags, unsigned int sharedKey, char *authKey); +extern bool parse_wd_node_function_json(char *json_data, int data_len, char **func_name, int **node_id_set, int *count, unsigned char *flags); +extern char *get_wd_simple_message_json(char *message); -extern WDPGBackendStatus* get_pg_backend_node_status_from_json(char* json_data, int data_len); -extern char* get_backend_node_status_json(WatchdogNode* wdNode); +extern WDPGBackendStatus * get_pg_backend_node_status_from_json(char *json_data, int data_len); +extern char *get_backend_node_status_json(WatchdogNode * wdNode); -extern char* get_simple_request_json(char *key, char* value, unsigned int sharedKey, char* authKey); +extern char *get_simple_request_json(char *key, char *value, unsigned int sharedKey, char *authKey); -extern bool parse_data_request_json(char* json_data, int data_len, char** request_type); -extern char* get_data_request_json(char* request_type, unsigned int sharedKey, char* authKey); +extern bool parse_data_request_json(char *json_data, int data_len, char **request_type); +extern char *get_data_request_json(char *request_type, unsigned int sharedKey, char *authKey); #endif diff --git a/src/include/watchdog/wd_lifecheck.h b/src/include/watchdog/wd_lifecheck.h index 4dae50d60..d612ab38e 100644 --- a/src/include/watchdog/wd_lifecheck.h +++ b/src/include/watchdog/wd_lifecheck.h @@ -34,28 +34,28 @@ typedef enum NodeState NODE_EMPTY, NODE_DEAD, NODE_ALIVE -}NodeStates; +} NodeStates; typedef struct LifeCheckNode { - NodeStates nodeState; - int ID; - char hostName[128]; - char nodeName[128]; - int wdPort; - int pgpoolPort; - int retry_lives; - struct timeval hb_send_time; /* send time */ - struct timeval hb_last_recv_time; /* recv time */ -}LifeCheckNode; + NodeStates nodeState; + int ID; + char hostName[128]; + char nodeName[128]; + int wdPort; + int pgpoolPort; + int retry_lives; + struct timeval hb_send_time; /* send time */ + struct timeval hb_last_recv_time; /* recv time */ +} LifeCheckNode; typedef struct lifeCheckCluster { - int nodeCount; - struct LifeCheckNode* lifeCheckNodes; -}LifeCheckCluster; + int nodeCount; + struct LifeCheckNode *lifeCheckNodes; +} LifeCheckCluster; -extern LifeCheckCluster* gslifeCheckCluster; /* lives in shared memory */ +extern LifeCheckCluster * gslifeCheckCluster; /* lives in shared memory */ /* wd_lifecheck.c */ diff --git a/src/include/watchdog/wd_utils.h b/src/include/watchdog/wd_utils.h index cd6567a29..cdf829c63 100644 --- a/src/include/watchdog/wd_utils.h +++ b/src/include/watchdog/wd_utils.h @@ -33,32 +33,33 @@ #define WD_MAX_PACKET_STRING (256) /* wd_utils.c*/ -extern int wd_chk_sticky(void); +extern int wd_chk_sticky(void); extern void wd_check_network_command_configurations(void); -extern int watchdog_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); +extern int watchdog_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg); extern char *string_replace(const char *string, const char *pattern, const char *replacement); extern void wd_calc_hash(const char *str, int len, char *buf); extern int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, - const char *password, unsigned char *plaintext); + const char *password, unsigned char *plaintext); extern int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, - const char *password, unsigned char *ciphertext); + const char *password, unsigned char *ciphertext); + /* wd_escalation.c */ extern pid_t fork_escalation_process(void); extern pid_t fork_plunging_process(void); /* wd_ping.c */ -extern int wd_is_upper_ok(char * server_list); -extern bool wd_is_ip_exists(char * ip); -extern bool wd_get_ping_result(char* hostname, int exit_status, int outfd); -extern pid_t wd_issue_ping_command(char* hostname, int* outfd); +extern int wd_is_upper_ok(char *server_list); +extern bool wd_is_ip_exists(char *ip); +extern bool wd_get_ping_result(char *hostname, int exit_status, int outfd); +extern pid_t wd_issue_ping_command(char *hostname, int *outfd); /* wd_if.c */ -extern List* get_all_local_ips(void); -extern int wd_IP_up(void); -extern int wd_IP_down(void); -extern char* wd_get_cmd(char* cmd); -extern int create_monitoring_socket(void); -extern bool read_interface_change_event(int sock, bool* link_event, bool* deleted); +extern List *get_all_local_ips(void); +extern int wd_IP_up(void); +extern int wd_IP_down(void); +extern char *wd_get_cmd(char *cmd); +extern int create_monitoring_socket(void); +extern bool read_interface_change_event(int sock, bool *link_event, bool *deleted); extern bool is_interface_up(struct ifaddrs *ifa); #endif diff --git a/src/libs/pcp/pcp.c b/src/libs/pcp/pcp.c index 7db312fef..47715b6c3 100644 --- a/src/libs/pcp/pcp.c +++ b/src/libs/pcp/pcp.c @@ -5,7 +5,7 @@ * These are client APIs. Server program should use APIs in pcp_stream.c * * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2016 PgPool Global Development Group @@ -51,36 +51,36 @@ #define DefaultHost "localhost" -static int pcp_authorize(PCPConnInfo* pcpConn, char *username, char *password); +static int pcp_authorize(PCPConnInfo * pcpConn, char *username, char *password); -static void pcp_internal_error(PCPConnInfo* pcpConn, const char *fmt,...); +static void pcp_internal_error(PCPConnInfo * pcpConn, const char *fmt,...); -static PCPResultInfo* _pcp_detach_node(PCPConnInfo* pcpConn, int nid, bool gracefully); -static PCPResultInfo* _pcp_promote_node(PCPConnInfo* pcpConn,int nid, bool gracefully); -static PCPResultInfo* process_pcp_response(PCPConnInfo* pcpConn, char sentMsg); -static void setCommandSuccessful(PCPConnInfo* pcpConn); -static void setResultStatus(PCPConnInfo* pcpConn, ResultStateType resultState); -static void setResultBinaryData(PCPResultInfo *res, unsigned int slotno, void *value, int datalen, void (*free_func)(struct PCPConnInfo*,void*) ); -static int setNextResultBinaryData(PCPResultInfo *res, void *value, int datalen, void (*free_func)(struct PCPConnInfo*,void*) ); -static void setResultIntData(PCPResultInfo *res, unsigned int slotno, int value); +static PCPResultInfo * _pcp_detach_node(PCPConnInfo * pcpConn, int nid, bool gracefully); +static PCPResultInfo * _pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully); +static PCPResultInfo * process_pcp_response(PCPConnInfo * pcpConn, char sentMsg); +static void setCommandSuccessful(PCPConnInfo * pcpConn); +static void setResultStatus(PCPConnInfo * pcpConn, ResultStateType resultState); +static void setResultBinaryData(PCPResultInfo * res, unsigned int slotno, void *value, int datalen, void (*free_func) (struct PCPConnInfo *, void *)); +static int setNextResultBinaryData(PCPResultInfo * res, void *value, int datalen, void (*free_func) (struct PCPConnInfo *, void *)); +static void setResultIntData(PCPResultInfo * res, unsigned int slotno, int value); -static void process_node_info_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_command_complete_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_process_info_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_pool_status_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_pcp_node_count_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_process_count_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_salt_info_response(PCPConnInfo* pcpConn, char* buf, int len); -static void process_error_response(PCPConnInfo* pcpConn, char toc, char* buff); +static void process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_command_complete_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_process_info_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_pool_status_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_pcp_node_count_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_process_count_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_salt_info_response(PCPConnInfo * pcpConn, char *buf, int len); +static void process_error_response(PCPConnInfo * pcpConn, char toc, char *buff); -static void setResultSlotCount(PCPConnInfo* pcpConn, unsigned int slotCount); -static void free_processInfo(struct PCPConnInfo* pcpConn, void* ptr); -static int PCPFlush(PCPConnInfo* pcpConn); +static void setResultSlotCount(PCPConnInfo * pcpConn, unsigned int slotCount); +static void free_processInfo(struct PCPConnInfo *pcpConn, void *ptr); +static int PCPFlush(PCPConnInfo * pcpConn); static bool getPoolPassFilename(char *pgpassfile); -static char *PasswordFromFile(PCPConnInfo* pcpConn, char *hostname, char *port, char *username); +static char *PasswordFromFile(PCPConnInfo * pcpConn, char *hostname, char *port, char *username); static char *pwdfMatchesString(char *buf, char *token); /* -------------------------------- @@ -94,32 +94,32 @@ static char *pwdfMatchesString(char *buf, char *token); * return 1 on successfull 0 otherwise */ -PCPConnInfo* +PCPConnInfo * pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfdebug) { struct sockaddr_in addr; struct sockaddr_un unix_addr; struct hostent *hp; - char *password_fron_file = NULL; - char os_user[256]; - PCPConnInfo* pcpConn = palloc0(sizeof(PCPConnInfo)); - int fd; - int on = 1; - int len; + char *password_fron_file = NULL; + char os_user[256]; + PCPConnInfo *pcpConn = palloc0(sizeof(PCPConnInfo)); + int fd; + int on = 1; + int len; pcpConn->connState = PCP_CONNECTION_NOT_CONNECTED; pcpConn->Pfdebug = Pfdebug; if (hostname == NULL || *hostname == '\0' || *hostname == '/') { - char *path; + char *path; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) { pcp_internal_error(pcpConn, - "ERROR: failed to create UNIX domain socket. socket error \"%s\"",strerror(errno)); + "ERROR: failed to create UNIX domain socket. socket error \"%s\"", strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; @@ -146,7 +146,7 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde close(fd); pcp_internal_error(pcpConn, - "ERROR: connection to socket \"%s\" failed with error \"%s\"",unix_addr.sun_path,strerror(errno)); + "ERROR: connection to socket \"%s\" failed with error \"%s\"", unix_addr.sun_path, strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } @@ -157,7 +157,7 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde if (fd < 0) { pcp_internal_error(pcpConn, - "ERROR: failed to create INET domain socket with error \"%s\"",strerror(errno)); + "ERROR: failed to create INET domain socket with error \"%s\"", strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } @@ -168,7 +168,7 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde close(fd); pcp_internal_error(pcpConn, - "ERROR: set socket option failed with error \"%s\"",strerror(errno)); + "ERROR: set socket option failed with error \"%s\"", strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } @@ -180,7 +180,7 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde { close(fd); pcp_internal_error(pcpConn, - "ERROR: could not retrieve hostname. gethostbyname failed with error \"%s\"",strerror(errno)); + "ERROR: could not retrieve hostname. gethostbyname failed with error \"%s\"", strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; @@ -195,7 +195,7 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde { close(fd); pcp_internal_error(pcpConn, - "ERROR: connection to host \"%s\" failed with error \"%s\"",hostname,strerror(errno)); + "ERROR: connection to host \"%s\" failed with error \"%s\"", hostname, strerror(errno)); pcpConn->connState = PCP_CONNECTION_BAD; return pcpConn; } @@ -213,8 +213,8 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde pcpConn->connState = PCP_CONNECTION_CONNECTED; /* - * If username is not provided. Use the os user name - * and do not complain if it (getting os user name) gets failed + * If username is not provided. Use the os user name and do not complain + * if it (getting os user name) gets failed */ if (username == NULL && get_os_username(os_user, sizeof(os_user))) username = os_user; @@ -224,13 +224,14 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde */ if (password == NULL || *password == '\0') { - char port_str[100]; - snprintf(port_str, sizeof(port_str), "%d",port); + char port_str[100]; + + snprintf(port_str, sizeof(port_str), "%d", port); password_fron_file = PasswordFromFile(pcpConn, hostname, port_str, username); password = password_fron_file; } - if (pcp_authorize(pcpConn,username, password) < 0) + if (pcp_authorize(pcpConn, username, password) < 0) { pcp_close(pcpConn->pcpConn); pcpConn->pcpConn = NULL; @@ -239,18 +240,19 @@ pcp_connect(char *hostname, int port, char *username, char *password, FILE *Pfde else pcpConn->connState = PCP_CONNECTION_OK; - if(password_fron_file) + if (password_fron_file) pfree(password_fron_file); return pcpConn; } static void -process_salt_info_response(PCPConnInfo* pcpConn, char* buf, int len) +process_salt_info_response(PCPConnInfo * pcpConn, char *buf, int len) { - char* salt = palloc((sizeof(char) * 4)); + char *salt = palloc((sizeof(char) * 4)); + memcpy(salt, buf, 4); - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)salt, 4, NULL) < 0 ) + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) salt, 4, NULL) < 0) { pcp_internal_error(pcpConn, @@ -262,6 +264,7 @@ process_salt_info_response(PCPConnInfo* pcpConn, char* buf, int len) setCommandSuccessful(pcpConn); } } + /* -------------------------------- * pcp_authorize - authenticate with pgpool using username and password * @@ -269,14 +272,14 @@ process_salt_info_response(PCPConnInfo* pcpConn, char* buf, int len) * -------------------------------- */ static int -pcp_authorize(PCPConnInfo* pcpConn, char *username, char *password) +pcp_authorize(PCPConnInfo * pcpConn, char *username, char *password) { - int wsize; - char salt[4]; - char* salt_ptr; - char encrypt_buf[(MD5_PASSWD_LEN+1)*2]; - char md5[MD5_PASSWD_LEN+1]; - PCPResultInfo* pcpRes; + int wsize; + char salt[4]; + char *salt_ptr; + char encrypt_buf[(MD5_PASSWD_LEN + 1) * 2]; + char md5[MD5_PASSWD_LEN + 1]; + PCPResultInfo *pcpRes; if (password == NULL) password = ""; @@ -306,11 +309,11 @@ pcp_authorize(PCPConnInfo* pcpConn, char *username, char *password) return -1; pcpRes = process_pcp_response(pcpConn, 'M'); - if(PCPResultStatus(pcpRes) != PCP_RES_COMMAND_OK) + if (PCPResultStatus(pcpRes) != PCP_RES_COMMAND_OK) return -1; salt_ptr = pcp_get_binary_data(pcpRes, 0); - if(salt_ptr == NULL) + if (salt_ptr == NULL) return -1; memcpy(salt, salt_ptr, 4); @@ -320,40 +323,41 @@ pcp_authorize(PCPConnInfo* pcpConn, char *username, char *password) pool_md5_encrypt(md5, username, strlen(username), encrypt_buf + MD5_PASSWD_LEN + 1); - encrypt_buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; + encrypt_buf[(MD5_PASSWD_LEN + 1) * 2 - 1] = '\0'; - pool_md5_encrypt(encrypt_buf+MD5_PASSWD_LEN+1, salt, 4, + pool_md5_encrypt(encrypt_buf + MD5_PASSWD_LEN + 1, salt, 4, encrypt_buf); encrypt_buf[MD5_PASSWD_LEN] = '\0'; pcp_write(pcpConn->pcpConn, "R", 1); - wsize = htonl((strlen(username)+1 + strlen(encrypt_buf)+1) + sizeof(int)); + wsize = htonl((strlen(username) + 1 + strlen(encrypt_buf) + 1) + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, username, strlen(username)+1); - pcp_write(pcpConn->pcpConn, encrypt_buf, strlen(encrypt_buf)+1); + pcp_write(pcpConn->pcpConn, username, strlen(username) + 1); + pcp_write(pcpConn->pcpConn, encrypt_buf, strlen(encrypt_buf) + 1); if (PCPFlush(pcpConn) < 0) return -1; pcpRes = process_pcp_response(pcpConn, 'R'); - if(PCPResultStatus(pcpRes) != PCP_RES_COMMAND_OK) + if (PCPResultStatus(pcpRes) != PCP_RES_COMMAND_OK) return -1; pcp_free_result(pcpConn); return 0; } -static PCPResultInfo* process_pcp_response(PCPConnInfo* pcpConn, char sentMsg) +static PCPResultInfo * process_pcp_response(PCPConnInfo * pcpConn, char sentMsg) { - char toc; - int rsize; - char* buf; + char toc; + int rsize; + char *buf; /* create empty result */ - if(pcpConn->pcpResInfo == NULL) + if (pcpConn->pcpResInfo == NULL) { pcpConn->pcpResInfo = palloc0(sizeof(PCPResultInfo)); pcpConn->pcpResInfo->resultSlots = 1; } - while (1) { + while (1) + { if (pcp_read(pcpConn->pcpConn, &toc, 1)) { pcp_internal_error(pcpConn, @@ -369,7 +373,7 @@ static PCPResultInfo* process_pcp_response(PCPConnInfo* pcpConn, char sentMsg) return pcpConn->pcpResInfo; } rsize = ntohl(rsize); - buf = (char *)palloc(rsize); + buf = (char *) palloc(rsize); if (pcp_read(pcpConn->pcpConn, buf, rsize - sizeof(int))) { @@ -380,112 +384,113 @@ static PCPResultInfo* process_pcp_response(PCPConnInfo* pcpConn, char sentMsg) return pcpConn->pcpResInfo; } - if(pcpConn->Pfdebug) + if (pcpConn->Pfdebug) fprintf(pcpConn->Pfdebug, "DEBUG: recv: tos=\"%c\", len=%d\n", toc, rsize); - switch (toc) { - case 'r': /* Authentication Response */ - { - if(sentMsg != 'R') - { - setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); - } - else if (strcmp(buf, "AuthenticationOK") == 0) - { - pcpConn->connState = PCP_CONNECTION_OK; - setResultStatus(pcpConn, PCP_RES_COMMAND_OK); - } - else + switch (toc) + { + case 'r': /* Authentication Response */ { - pcp_internal_error(pcpConn, - "ERROR: authentication failed. reason=\"%s\"", buf); - setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); + if (sentMsg != 'R') + { + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + } + else if (strcmp(buf, "AuthenticationOK") == 0) + { + pcpConn->connState = PCP_CONNECTION_OK; + setResultStatus(pcpConn, PCP_RES_COMMAND_OK); + } + else + { + pcp_internal_error(pcpConn, + "ERROR: authentication failed. reason=\"%s\"", buf); + setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); + } } - } - break; + break; case 'm': - if(sentMsg != 'M') + if (sentMsg != 'M') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_salt_info_response(pcpConn,buf,rsize); + process_salt_info_response(pcpConn, buf, rsize); break; case 'E': setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); - process_error_response(pcpConn,toc,buf); + process_error_response(pcpConn, toc, buf); break; case 'N': - process_error_response(pcpConn,toc,buf); + process_error_response(pcpConn, toc, buf); pfree(buf); continue; break; case 'i': - if(sentMsg != 'I') + if (sentMsg != 'I') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_node_info_response(pcpConn,buf,rsize); + process_node_info_response(pcpConn, buf, rsize); break; case 'l': - if(sentMsg != 'L') + if (sentMsg != 'L') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_pcp_node_count_response(pcpConn,buf,rsize); + process_pcp_node_count_response(pcpConn, buf, rsize); break; case 'c': - if(sentMsg != 'C' && sentMsg != 'O') + if (sentMsg != 'C' && sentMsg != 'O') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_command_complete_response(pcpConn,buf,rsize); + process_command_complete_response(pcpConn, buf, rsize); break; case 'd': - if(sentMsg != 'D' && sentMsg != 'J') + if (sentMsg != 'D' && sentMsg != 'J') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_command_complete_response(pcpConn,buf,rsize); + process_command_complete_response(pcpConn, buf, rsize); break; case 'a': - if(sentMsg != 'A') + if (sentMsg != 'A') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_command_complete_response(pcpConn,buf,rsize); + process_command_complete_response(pcpConn, buf, rsize); break; case 'w': - if(sentMsg != 'W') + if (sentMsg != 'W') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_watchdog_info_response(pcpConn,buf,rsize); + process_watchdog_info_response(pcpConn, buf, rsize); break; case 'p': - if(sentMsg != 'P') + if (sentMsg != 'P') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_process_info_response(pcpConn,buf,rsize); + process_process_info_response(pcpConn, buf, rsize); break; case 'n': - if(sentMsg != 'N') + if (sentMsg != 'N') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_process_count_response(pcpConn,buf,rsize); + process_process_count_response(pcpConn, buf, rsize); break; case 'b': - if(sentMsg != 'B') + if (sentMsg != 'B') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else - process_pool_status_response(pcpConn,buf,rsize); + process_pool_status_response(pcpConn, buf, rsize); break; case 't': - if(sentMsg != 'T') + if (sentMsg != 'T') setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); else setResultStatus(pcpConn, PCP_RES_COMMAND_OK); @@ -498,77 +503,79 @@ static PCPResultInfo* process_pcp_response(PCPConnInfo* pcpConn, char sentMsg) break; } pfree(buf); - if( PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) + if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) break; } return pcpConn->pcpResInfo; } static void -process_error_response(PCPConnInfo* pcpConn, char toc, char* buf) +process_error_response(PCPConnInfo * pcpConn, char toc, char *buf) { /* For time we only support sev, error message and details */ - char *errorSev = NULL; - char *errorMsg = NULL; - char *errorDet = NULL; - char *e = buf; + char *errorSev = NULL; + char *errorMsg = NULL; + char *errorDet = NULL; + char *e = buf; - if(toc != 'E' && toc != 'N') + if (toc != 'E' && toc != 'N') return; while (*e) { - char type = *e; + char type = *e; + e++; - if(*e == 0) + if (*e == 0) break; if (type == 'M') errorMsg = e; - else if(type == 'S') + else if (type == 'S') errorSev = e; - else if(type == 'D') + else if (type == 'D') errorDet = e; else e += strlen(e) + 1; - if(errorDet && errorSev && errorMsg) /* we have all what we need */ + if (errorDet && errorSev && errorMsg) /* we have all what we need */ break; } - if(!errorSev && !errorMsg) + if (!errorSev && !errorMsg) return; - if(toc != 'E') /* This is not an error report it as debug */ + if (toc != 'E') /* This is not an error report it as debug */ { - if(pcpConn->Pfdebug) + if (pcpConn->Pfdebug) fprintf(pcpConn->Pfdebug, - "BACKEND %s: %s\n%s%s%s",errorSev, errorMsg, - errorDet?"DETAIL: ":"", - errorDet?errorDet:"", - errorDet?"\n":""); + "BACKEND %s: %s\n%s%s%s", errorSev, errorMsg, + errorDet ? "DETAIL: " : "", + errorDet ? errorDet : "", + errorDet ? "\n" : ""); } else { pcp_internal_error(pcpConn, - "%s: %s\n%s%s%s",errorSev, errorMsg, - errorDet?"DETAIL: ":"", - errorDet?errorDet:"", - errorDet?"\n":""); + "%s: %s\n%s%s%s", errorSev, errorMsg, + errorDet ? "DETAIL: " : "", + errorDet ? errorDet : "", + errorDet ? "\n" : ""); setResultStatus(pcpConn, PCP_RES_BACKEND_ERROR); } } + /* -------------------------------- * pcp_disconnect - close connection to pgpool * -------------------------------- */ void -pcp_disconnect(PCPConnInfo* pcpConn) +pcp_disconnect(PCPConnInfo * pcpConn) { - int wsize; + int wsize; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return; } @@ -577,7 +584,7 @@ pcp_disconnect(PCPConnInfo* pcpConn) pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); if (PCPFlush(pcpConn) < 0) return; - if(pcpConn->Pfdebug) + if (pcpConn->Pfdebug) fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"X\", len=%d\n", (int) sizeof(int)); pcp_close(pcpConn->pcpConn); @@ -591,13 +598,14 @@ pcp_disconnect(PCPConnInfo* pcpConn) * return 0 on success, -1 otherwise * -------------------------------- */ -PCPResultInfo *pcp_terminate_pgpool(PCPConnInfo* pcpConn, char mode) +PCPResultInfo * +pcp_terminate_pgpool(PCPConnInfo * pcpConn, char mode) { - int wsize; + int wsize; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } pcp_write(pcpConn->pcpConn, "T", 1); @@ -606,23 +614,24 @@ PCPResultInfo *pcp_terminate_pgpool(PCPConnInfo* pcpConn, char mode) pcp_write(pcpConn->pcpConn, &mode, sizeof(char)); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"T\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"T\", len=%d\n", ntohl(wsize)); return process_pcp_response(pcpConn, 'T'); } static void -process_pcp_node_count_response(PCPConnInfo* pcpConn, char* buf, int len) +process_pcp_node_count_response(PCPConnInfo * pcpConn, char *buf, int len) { if (strcmp(buf, "CommandComplete") == 0) { - char *index = NULL; + char *index = NULL; index = (char *) memchr(buf, '\0', len); if (index != NULL) { - int ret; + int ret; + index += 1; ret = atoi(index); setResultIntData(pcpConn->pcpResInfo, 0, ret); @@ -635,21 +644,22 @@ process_pcp_node_count_response(PCPConnInfo* pcpConn, char* buf, int len) } else pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"",buf); + "command failed with reason: \"%s\"", buf); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } + /* -------------------------------- * pcp_node_count - get number of nodes currently connected to pgpool * * return array of node IDs on success, -1 otherwise * -------------------------------- */ -PCPResultInfo* -pcp_node_count(PCPConnInfo* pcpConn) +PCPResultInfo * +pcp_node_count(PCPConnInfo * pcpConn) { - int wsize; + int wsize; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { pcp_internal_error(pcpConn, "invalid PCP connection"); @@ -660,72 +670,73 @@ pcp_node_count(PCPConnInfo* pcpConn) pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) + if (pcpConn->Pfdebug) fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"L\", len=%d\n", ntohl(wsize)); return process_pcp_response(pcpConn, 'L'); } static void -process_node_info_response(PCPConnInfo* pcpConn, char* buf, int len) +process_node_info_response(PCPConnInfo * pcpConn, char *buf, int len) { - BackendInfo* backend_info = NULL; + BackendInfo *backend_info = NULL; + if (strcmp(buf, "CommandComplete") == 0) { - char *index = NULL; + char *index = NULL; - backend_info = (BackendInfo *)palloc(sizeof(BackendInfo)); + backend_info = (BackendInfo *) palloc(sizeof(BackendInfo)); index = (char *) memchr(buf, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; strlcpy(backend_info->backend_hostname, index, sizeof(backend_info->backend_hostname)); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; backend_info->backend_port = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; backend_info->backend_status = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; backend_info->backend_weight = atof(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; index++; backend_info->role = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; index++; backend_info->standby_delay = atol(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; index++; backend_info->status_changed_time = atol(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)backend_info, sizeof(BackendInfo) , NULL) < 0) + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) backend_info, sizeof(BackendInfo), NULL) < 0) goto INVALID_RESPONSE; setCommandSuccessful(pcpConn); @@ -733,7 +744,7 @@ process_node_info_response(PCPConnInfo* pcpConn, char* buf, int len) else { pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"",buf); + "command failed with reason: \"%s\"", buf); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } @@ -741,13 +752,14 @@ process_node_info_response(PCPConnInfo* pcpConn, char* buf, int len) INVALID_RESPONSE: - if(backend_info) + if (backend_info) pfree(backend_info); pcp_internal_error(pcpConn, "command failed. invalid response"); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } + /* -------------------------------- * pcp_node_info - get information of node pointed by given argument * @@ -755,12 +767,12 @@ INVALID_RESPONSE: * -------------------------------- */ PCPResultInfo * -pcp_node_info(PCPConnInfo* pcpConn, int nid) +pcp_node_info(PCPConnInfo * pcpConn, int nid) { - int wsize; - char node_id[16]; + int wsize; + char node_id[16]; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { pcp_internal_error(pcpConn, "invalid PCP connection"); @@ -770,26 +782,26 @@ pcp_node_info(PCPConnInfo* pcpConn, int nid) snprintf(node_id, sizeof(node_id), "%d", nid); pcp_write(pcpConn->pcpConn, "I", 1); - wsize = htonl(strlen(node_id)+1 + sizeof(int)); + wsize = htonl(strlen(node_id) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, node_id, strlen(node_id)+1); + pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"I\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"I\", len=%d\n", ntohl(wsize)); - return process_pcp_response(pcpConn,'I'); + return process_pcp_response(pcpConn, 'I'); } static void -process_process_count_response(PCPConnInfo* pcpConn, char* buf, int len) +process_process_count_response(PCPConnInfo * pcpConn, char *buf, int len) { if (strcmp(buf, "CommandComplete") == 0) { - int process_count; - int *process_list = NULL; - char *index = NULL; - int i; + int process_count; + int *process_list = NULL; + char *index = NULL; + int i; index = (char *) memchr(buf, '\0', len); if (index == NULL) @@ -799,10 +811,10 @@ process_process_count_response(PCPConnInfo* pcpConn, char* buf, int len) setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); return; } - index +=1; + index += 1; process_count = atoi(index); - process_list = (int *)palloc(sizeof(int) * process_count); + process_list = (int *) palloc(sizeof(int) * process_count); for (i = 0; i < process_count; i++) { @@ -814,11 +826,11 @@ process_process_count_response(PCPConnInfo* pcpConn, char* buf, int len) setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); return; } - index +=1; + index += 1; process_list[i] = atoi(index); } - setResultSlotCount(pcpConn,1); - if (setNextResultBinaryData(pcpConn->pcpResInfo, process_list, (sizeof(int) * process_count) , NULL) < 0) + setResultSlotCount(pcpConn, 1); + if (setNextResultBinaryData(pcpConn->pcpResInfo, process_list, (sizeof(int) * process_count), NULL) < 0) { pcp_internal_error(pcpConn, "command failed. invalid response"); @@ -832,10 +844,11 @@ process_process_count_response(PCPConnInfo* pcpConn, char* buf, int len) else { pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"",buf); + "command failed with reason: \"%s\"", buf); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } } + /* -------------------------------- * pcp_node_count - get number of nodes currently connected to pgpool * @@ -844,13 +857,13 @@ process_process_count_response(PCPConnInfo* pcpConn, char* buf, int len) */ PCPResultInfo * -pcp_process_count(PCPConnInfo* pcpConn) +pcp_process_count(PCPConnInfo * pcpConn) { - int wsize; + int wsize; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } @@ -859,43 +872,45 @@ pcp_process_count(PCPConnInfo* pcpConn) pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"N\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"N\", len=%d\n", ntohl(wsize)); - return process_pcp_response(pcpConn,'N'); + return process_pcp_response(pcpConn, 'N'); } static void -free_processInfo(struct PCPConnInfo* pcpConn, void* ptr) +free_processInfo(struct PCPConnInfo *pcpConn, void *ptr) { - ProcessInfo * pi = (ProcessInfo *)ptr; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"free ProcessInfo structure \n"); + ProcessInfo *pi = (ProcessInfo *) ptr; + + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "free ProcessInfo structure \n"); if (pi == NULL) { - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"ProcessInfo structure is NULL nothing to free \n"); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "ProcessInfo structure is NULL nothing to free \n"); return; } - if(pi->connection_info) + if (pi->connection_info) pfree(pi->connection_info); pfree(pi); } static void -process_process_info_response(PCPConnInfo* pcpConn, char* buf, int len) +process_process_info_response(PCPConnInfo * pcpConn, char *buf, int len) { - char *index; + char *index; ProcessInfo *processInfo = NULL; if (strcmp(buf, "ArraySize") == 0) { - int ci_size; + int ci_size; + index = (char *) memchr(buf, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; ci_size = atoi(index); setResultStatus(pcpConn, PCP_RES_INCOMPLETE); @@ -905,79 +920,79 @@ process_process_info_response(PCPConnInfo* pcpConn, char* buf, int len) } else if (strcmp(buf, "ProcessInfo") == 0) { - if(PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) + if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) goto INVALID_RESPONSE; processInfo = palloc0(sizeof(ProcessInfo)); processInfo->connection_info = palloc0(sizeof(ConnectionInfo)); index = (char *) memchr(buf, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->pid = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; strlcpy(processInfo->connection_info->database, index, SM_DATABASE); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; strlcpy(processInfo->connection_info->user, index, SM_USER); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->start_time = atol(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->create_time = atol(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->major = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->minor = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->counter = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->backend_id = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->pid = atoi(index); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; + index += 1; processInfo->connection_info->connected = atoi(index); - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)processInfo, sizeof(ProcessInfo), free_processInfo) < 0) + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) processInfo, sizeof(ProcessInfo), free_processInfo) < 0) goto INVALID_RESPONSE; return; @@ -990,10 +1005,10 @@ process_process_info_response(PCPConnInfo* pcpConn, char* buf, int len) } INVALID_RESPONSE: - - if(processInfo) + + if (processInfo) { - if(processInfo->connection_info) + if (processInfo->connection_info) pfree(processInfo->connection_info); pfree(processInfo); } @@ -1009,29 +1024,29 @@ INVALID_RESPONSE: * -------------------------------- */ PCPResultInfo * -pcp_process_info(PCPConnInfo* pcpConn, int pid) +pcp_process_info(PCPConnInfo * pcpConn, int pid) { - int wsize; - char process_id[16]; + int wsize; + char process_id[16]; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } snprintf(process_id, sizeof(process_id), "%d", pid); pcp_write(pcpConn->pcpConn, "P", 1); - wsize = htonl(strlen(process_id)+1 + sizeof(int)); + wsize = htonl(strlen(process_id) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, process_id, strlen(process_id)+1); + pcp_write(pcpConn->pcpConn, process_id, strlen(process_id) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) + if (pcpConn->Pfdebug) fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"P\", len=%d\n", ntohl(wsize)); - return process_pcp_response(pcpConn,'P'); + return process_pcp_response(pcpConn, 'P'); } /* -------------------------------- @@ -1040,10 +1055,10 @@ pcp_process_info(PCPConnInfo* pcpConn, int pid) * return 0 on success, -1 otherwise * -------------------------------- */ -PCPResultInfo* -pcp_detach_node(PCPConnInfo* pcpConn, int nid) +PCPResultInfo * +pcp_detach_node(PCPConnInfo * pcpConn, int nid) { - return _pcp_detach_node(pcpConn, nid, FALSE); + return _pcp_detach_node(pcpConn, nid, FALSE); } /* -------------------------------- @@ -1053,46 +1068,46 @@ pcp_detach_node(PCPConnInfo* pcpConn, int nid) * return 0 on success, -1 otherwise * -------------------------------- */ -PCPResultInfo* -pcp_detach_node_gracefully(PCPConnInfo* pcpConn, int nid) +PCPResultInfo * +pcp_detach_node_gracefully(PCPConnInfo * pcpConn, int nid) { - return _pcp_detach_node(pcpConn, nid, TRUE); + return _pcp_detach_node(pcpConn, nid, TRUE); } -static PCPResultInfo* -_pcp_detach_node(PCPConnInfo* pcpConn, int nid, bool gracefully) +static PCPResultInfo * +_pcp_detach_node(PCPConnInfo * pcpConn, int nid, bool gracefully) { - int wsize; - char node_id[16]; - char *sendchar; + int wsize; + char node_id[16]; + char *sendchar; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } snprintf(node_id, sizeof(node_id), "%d", nid); if (gracefully) - sendchar = "d"; + sendchar = "d"; else - sendchar = "D"; + sendchar = "D"; pcp_write(pcpConn->pcpConn, sendchar, 1); - wsize = htonl(strlen(node_id)+1 + sizeof(int)); + wsize = htonl(strlen(node_id) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, node_id, strlen(node_id)+1); + pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); return process_pcp_response(pcpConn, 'D'); } static void -process_command_complete_response(PCPConnInfo* pcpConn, char* buf, int len) +process_command_complete_response(PCPConnInfo * pcpConn, char *buf, int len) { if (strcmp(buf, "CommandComplete") == 0) { @@ -1101,8 +1116,8 @@ process_command_complete_response(PCPConnInfo* pcpConn, char* buf, int len) else { pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"",buf); - setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); + "command failed with reason: \"%s\"", buf); + setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } } @@ -1112,28 +1127,28 @@ process_command_complete_response(PCPConnInfo* pcpConn, char* buf, int len) * return 0 on success, -1 otherwise * -------------------------------- */ -PCPResultInfo* -pcp_attach_node(PCPConnInfo* pcpConn, int nid) +PCPResultInfo * +pcp_attach_node(PCPConnInfo * pcpConn, int nid) { - int wsize; - char node_id[16]; + int wsize; + char node_id[16]; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } snprintf(node_id, sizeof(node_id), "%d", nid); pcp_write(pcpConn->pcpConn, "C", 1); - wsize = htonl(strlen(node_id)+1 + sizeof(int)); + wsize = htonl(strlen(node_id) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, node_id, strlen(node_id)+1); + pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"C\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"C\", len=%d\n", ntohl(wsize)); return process_pcp_response(pcpConn, 'C'); } @@ -1146,16 +1161,17 @@ pcp_attach_node(PCPConnInfo* pcpConn, int nid) * -------------------------------- */ static void -process_pool_status_response(PCPConnInfo* pcpConn, char* buf, int len) +process_pool_status_response(PCPConnInfo * pcpConn, char *buf, int len) { - char *index; + char *index; POOL_REPORT_CONFIG *status = NULL; if (strcmp(buf, "ArraySize") == 0) { - int ci_size; + int ci_size; + index = (char *) memchr(buf, '\0', len) + 1; - ci_size = ntohl(*((int *)index)); + ci_size = ntohl(*((int *) index)); setResultStatus(pcpConn, PCP_RES_INCOMPLETE); setResultSlotCount(pcpConn, ci_size); @@ -1164,30 +1180,30 @@ process_pool_status_response(PCPConnInfo* pcpConn, char* buf, int len) } else if (strcmp(buf, "ProcessConfig") == 0) { - if(PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) + if (PCPResultStatus(pcpConn->pcpResInfo) != PCP_RES_INCOMPLETE) goto INVALID_RESPONSE; status = palloc(sizeof(POOL_REPORT_CONFIG)); index = (char *) memchr(buf, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; - strlcpy(status->name, index, POOLCONFIG_MAXNAMELEN+1); + index += 1; + strlcpy(status->name, index, POOLCONFIG_MAXNAMELEN + 1); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; - strlcpy(status->value, index, POOLCONFIG_MAXVALLEN+1); + index += 1; + strlcpy(status->value, index, POOLCONFIG_MAXVALLEN + 1); index = (char *) memchr(index, '\0', len); - if(index == NULL) + if (index == NULL) goto INVALID_RESPONSE; - index +=1; - strlcpy(status->desc, index, POOLCONFIG_MAXDESCLEN+1); + index += 1; + strlcpy(status->desc, index, POOLCONFIG_MAXDESCLEN + 1); - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)status, sizeof(POOL_REPORT_CONFIG) , NULL) < 0) + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) status, sizeof(POOL_REPORT_CONFIG), NULL) < 0) goto INVALID_RESPONSE; return; } @@ -1198,22 +1214,22 @@ process_pool_status_response(PCPConnInfo* pcpConn, char* buf, int len) } INVALID_RESPONSE: - - if(status) + + if (status) pfree(status); pcp_internal_error(pcpConn, "command failed. invalid response"); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } -PCPResultInfo* -pcp_pool_status(PCPConnInfo *pcpConn) +PCPResultInfo * +pcp_pool_status(PCPConnInfo * pcpConn) { - int wsize; + int wsize; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } @@ -1229,29 +1245,29 @@ pcp_pool_status(PCPConnInfo *pcpConn) PCPResultInfo * -pcp_recovery_node(PCPConnInfo* pcpConn, int nid) +pcp_recovery_node(PCPConnInfo * pcpConn, int nid) { - int wsize; - char node_id[16]; + int wsize; + char node_id[16]; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } snprintf(node_id, sizeof(node_id), "%d", nid); pcp_write(pcpConn->pcpConn, "O", 1); - wsize = htonl(strlen(node_id)+1 + sizeof(int)); + wsize = htonl(strlen(node_id) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, node_id, strlen(node_id)+1); + pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"D\", len=%d\n", ntohl(wsize)); - return process_pcp_response(pcpConn,'O'); + return process_pcp_response(pcpConn, 'O'); } /* -------------------------------- @@ -1261,9 +1277,9 @@ pcp_recovery_node(PCPConnInfo* pcpConn, int nid) * -------------------------------- */ PCPResultInfo * -pcp_promote_node(PCPConnInfo* pcpConn,int nid) +pcp_promote_node(PCPConnInfo * pcpConn, int nid) { - return _pcp_promote_node(pcpConn,nid, FALSE); + return _pcp_promote_node(pcpConn, nid, FALSE); } /* -------------------------------- @@ -1274,63 +1290,66 @@ pcp_promote_node(PCPConnInfo* pcpConn,int nid) * -------------------------------- */ PCPResultInfo * -pcp_promote_node_gracefully(PCPConnInfo* pcpConn,int nid) +pcp_promote_node_gracefully(PCPConnInfo * pcpConn, int nid) { - return _pcp_promote_node(pcpConn,nid, TRUE); + return _pcp_promote_node(pcpConn, nid, TRUE); } static PCPResultInfo * -_pcp_promote_node(PCPConnInfo* pcpConn,int nid, bool gracefully) +_pcp_promote_node(PCPConnInfo * pcpConn, int nid, bool gracefully) { - int wsize; - char node_id[16]; - char *sendchar; + int wsize; + char node_id[16]; + char *sendchar; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } snprintf(node_id, sizeof(node_id), "%d", nid); if (gracefully) - sendchar = "j"; + sendchar = "j"; else - sendchar = "J"; + sendchar = "J"; pcp_write(pcpConn->pcpConn, sendchar, 1); - wsize = htonl(strlen(node_id)+1 + sizeof(int)); + wsize = htonl(strlen(node_id) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, node_id, strlen(node_id)+1); + pcp_write(pcpConn->pcpConn, node_id, strlen(node_id) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"E\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"E\", len=%d\n", ntohl(wsize)); return process_pcp_response(pcpConn, 'J'); } static void -process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) +process_watchdog_info_response(PCPConnInfo * pcpConn, char *buf, int len) { - char *json_data = NULL; - PCPWDClusterInfo* wd_cluster_info = NULL; - int clusterDataSize = 0; + char *json_data = NULL; + PCPWDClusterInfo *wd_cluster_info = NULL; + int clusterDataSize = 0; + if (strcmp(buf, "CommandComplete") == 0) { - int tempVal; - char* ptr; + int tempVal; + char *ptr; + json_data = (char *) memchr(buf, '\0', len); - if(json_data == NULL) + if (json_data == NULL) goto INVALID_RESPONSE; - json_data +=1; + json_data += 1; - json_value* root; - json_value* value; - int i,nodeCount; + json_value *root; + json_value *value; + int i, + nodeCount; - root = json_parse(json_data,len); + root = json_parse(json_data, len); /* The root node must be object */ if (root == NULL || root->type != json_object) @@ -1346,7 +1365,7 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) } /* find the WatchdogNodes array */ - value = json_get_value_for_key(root,"WatchdogNodes"); + value = json_get_value_for_key(root, "WatchdogNodes"); if (value == NULL) { json_value_free(root); @@ -1389,7 +1408,7 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - wd_cluster_info->escalated = tempVal==0?false:true; + wd_cluster_info->escalated = tempVal == 0 ? false : true; ptr = json_get_string_value_for_key(root, "MasterNodeName"); if (ptr == NULL) @@ -1397,7 +1416,7 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wd_cluster_info->masterNodeName, ptr, sizeof(wd_cluster_info->masterNodeName) -1); + strncpy(wd_cluster_info->masterNodeName, ptr, sizeof(wd_cluster_info->masterNodeName) - 1); ptr = json_get_string_value_for_key(root, "MasterHostName"); if (ptr == NULL) @@ -1405,14 +1424,14 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wd_cluster_info->masterHostName, ptr, sizeof(wd_cluster_info->masterHostName) -1); + strncpy(wd_cluster_info->masterHostName, ptr, sizeof(wd_cluster_info->masterHostName) - 1); /* Get watchdog nodes data */ for (i = 0; i < nodeCount; i++) { - char* ptr; - json_value* nodeInfoValue = value->u.array.values[i]; - PCPWDNodeInfo* wdNodeInfo = &wd_cluster_info->nodeList[i]; + char *ptr; + json_value *nodeInfoValue = value->u.array.values[i]; + PCPWDNodeInfo *wdNodeInfo = &wd_cluster_info->nodeList[i]; if (nodeInfoValue->type != json_object) { @@ -1432,7 +1451,7 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) -1); + strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) - 1); ptr = json_get_string_value_for_key(nodeInfoValue, "HostName"); if (ptr == NULL) @@ -1440,7 +1459,7 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) -1); + strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) - 1); ptr = json_get_string_value_for_key(nodeInfoValue, "DelegateIP"); if (ptr == NULL) @@ -1448,7 +1467,7 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) -1); + strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) - 1); if (json_get_int_value_for_key(nodeInfoValue, "WdPort", &wdNodeInfo->wd_port)) { @@ -1474,8 +1493,8 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) json_value_free(root); goto INVALID_RESPONSE; } - strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) -1); - + strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) - 1); + if (json_get_int_value_for_key(nodeInfoValue, "Priority", &wdNodeInfo->wd_priority)) { json_value_free(root); @@ -1485,22 +1504,22 @@ process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) } json_value_free(root); - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)wd_cluster_info,clusterDataSize , NULL) < 0) + if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *) wd_cluster_info, clusterDataSize, NULL) < 0) goto INVALID_RESPONSE; - + setCommandSuccessful(pcpConn); } else { pcp_internal_error(pcpConn, - "command failed with reason: \"%s\"\n",buf); + "command failed with reason: \"%s\"\n", buf); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } return; INVALID_RESPONSE: - - if(wd_cluster_info) + + if (wd_cluster_info) pfree(wd_cluster_info); pcp_internal_error(pcpConn, "command failed. invalid response\n"); @@ -1514,45 +1533,45 @@ INVALID_RESPONSE: * -------------------------------- */ PCPResultInfo * -pcp_watchdog_info(PCPConnInfo* pcpConn, int nid) +pcp_watchdog_info(PCPConnInfo * pcpConn, int nid) { - int wsize; - char wd_index[16]; + int wsize; + char wd_index[16]; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } snprintf(wd_index, sizeof(wd_index), "%d", nid); pcp_write(pcpConn->pcpConn, "W", 1); - wsize = htonl(strlen(wd_index)+1 + sizeof(int)); + wsize = htonl(strlen(wd_index) + 1 + sizeof(int)); pcp_write(pcpConn->pcpConn, &wsize, sizeof(int)); - pcp_write(pcpConn->pcpConn, wd_index, strlen(wd_index)+1); + pcp_write(pcpConn->pcpConn, wd_index, strlen(wd_index) + 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"W\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"W\", len=%d\n", ntohl(wsize)); return process_pcp_response(pcpConn, 'W'); } PCPResultInfo * -pcp_set_backend_parameter(PCPConnInfo* pcpConn,char* parameter_name, char* value) +pcp_set_backend_parameter(PCPConnInfo * pcpConn, char *parameter_name, char *value) { - int wsize; - char null_chr = 0; + int wsize; + char null_chr = 0; - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - pcp_internal_error(pcpConn,"invalid PCP connection"); + pcp_internal_error(pcpConn, "invalid PCP connection"); return NULL; } - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: seting: \"%s = %s\"\n", parameter_name,value); - + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: seting: \"%s = %s\"\n", parameter_name, value); + pcp_write(pcpConn->pcpConn, "A", 1); wsize = htonl(strlen(parameter_name) + 1 + strlen(value) + 1 + @@ -1564,10 +1583,10 @@ pcp_set_backend_parameter(PCPConnInfo* pcpConn,char* parameter_name, char* value pcp_write(pcpConn->pcpConn, &null_chr, 1); if (PCPFlush(pcpConn) < 0) return NULL; - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug,"DEBUG: send: tos=\"A\", len=%d\n", ntohl(wsize)); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "DEBUG: send: tos=\"A\", len=%d\n", ntohl(wsize)); - return process_pcp_response(pcpConn,'A'); + return process_pcp_response(pcpConn, 'A'); } /* @@ -1579,7 +1598,7 @@ pcp_set_backend_parameter(PCPConnInfo* pcpConn,char* parameter_name, char* value * a trailing newline, and should not be more than one line). */ static void -pcp_internal_error(PCPConnInfo* pcpConn, const char *fmt,...) +pcp_internal_error(PCPConnInfo * pcpConn, const char *fmt,...) { char msgBuf[1024]; va_list args; @@ -1592,13 +1611,13 @@ pcp_internal_error(PCPConnInfo* pcpConn, const char *fmt,...) vsnprintf(msgBuf, sizeof(msgBuf), fmt, args); va_end(args); msgBuf[sizeof(msgBuf) - 1] = '\0'; /* make real sure it's terminated */ - if(pcpConn->errMsg) + if (pcpConn->errMsg) pfree(pcpConn->errMsg); pcpConn->errMsg = pstrdup(msgBuf); } ConnStateType -PCPConnectionStatus(const PCPConnInfo *conn) +PCPConnectionStatus(const PCPConnInfo * conn) { if (!conn) return PCP_CONNECTION_BAD; @@ -1606,7 +1625,7 @@ PCPConnectionStatus(const PCPConnInfo *conn) } ResultStateType -PCPResultStatus(const PCPResultInfo *res) +PCPResultStatus(const PCPResultInfo * res) { if (!res) return PCP_RES_ERROR; @@ -1614,38 +1633,38 @@ PCPResultStatus(const PCPResultInfo *res) } static void -setResultStatus(PCPConnInfo* pcpConn, ResultStateType resultState) +setResultStatus(PCPConnInfo * pcpConn, ResultStateType resultState) { - if(pcpConn && pcpConn->pcpResInfo) + if (pcpConn && pcpConn->pcpResInfo) pcpConn->pcpResInfo->resultStatus = resultState; } static void -setCommandSuccessful(PCPConnInfo* pcpConn) +setCommandSuccessful(PCPConnInfo * pcpConn) { - setResultStatus(pcpConn,PCP_RES_COMMAND_OK); + setResultStatus(pcpConn, PCP_RES_COMMAND_OK); } static void -setResultSlotCount(PCPConnInfo* pcpConn, unsigned int slotCount) +setResultSlotCount(PCPConnInfo * pcpConn, unsigned int slotCount) { - if(pcpConn && pcpConn->pcpResInfo && slotCount > 0) + if (pcpConn && pcpConn->pcpResInfo && slotCount > 0) { - if(pcpConn->pcpResInfo->resultSlots == 0) + if (pcpConn->pcpResInfo->resultSlots == 0) pcpConn->pcpResInfo->resultSlots = 1; - if(slotCount > pcpConn->pcpResInfo->resultSlots) + if (slotCount > pcpConn->pcpResInfo->resultSlots) { - pcpConn->pcpResInfo = repalloc(pcpConn->pcpResInfo, sizeof(PCPResultInfo) + (sizeof(PCPResultSlot) * (slotCount -1))); + pcpConn->pcpResInfo = repalloc(pcpConn->pcpResInfo, sizeof(PCPResultInfo) + (sizeof(PCPResultSlot) * (slotCount - 1))); } pcpConn->pcpResInfo->resultSlots = slotCount; } } static void -setResultIntData(PCPResultInfo *res, unsigned int slotno, int value) +setResultIntData(PCPResultInfo * res, unsigned int slotno, int value) { - if(res) + if (res) { res->resultSlot[slotno].datalen = 0; res->resultSlot[slotno].isint = 1; @@ -1655,9 +1674,9 @@ setResultIntData(PCPResultInfo *res, unsigned int slotno, int value) } static void -setResultBinaryData(PCPResultInfo *res, unsigned int slotno, void *value, int datalen, void (*free_func)(struct PCPConnInfo*,void*)) +setResultBinaryData(PCPResultInfo * res, unsigned int slotno, void *value, int datalen, void (*free_func) (struct PCPConnInfo *, void *)) { - if(res) + if (res) { res->resultSlot[slotno].datalen = datalen; res->resultSlot[slotno].isint = 0; @@ -1667,11 +1686,11 @@ setResultBinaryData(PCPResultInfo *res, unsigned int slotno, void *value, int da } static int -setNextResultBinaryData(PCPResultInfo *res, void *value, int datalen, void (*free_func)(struct PCPConnInfo*,void*)) +setNextResultBinaryData(PCPResultInfo * res, void *value, int datalen, void (*free_func) (struct PCPConnInfo *, void *)) { - if(res && res->nextFillSlot < res->resultSlots) + if (res && res->nextFillSlot < res->resultSlots) { - setResultBinaryData(res,res->nextFillSlot,value,datalen, free_func); + setResultBinaryData(res, res->nextFillSlot, value, datalen, free_func); res->nextFillSlot++; return res->nextFillSlot; } @@ -1679,24 +1698,27 @@ setNextResultBinaryData(PCPResultInfo *res, void *value, int datalen, void (*fre } static int -PCPFlush(PCPConnInfo* pcpConn) +PCPFlush(PCPConnInfo * pcpConn) { - int ret = pcp_flush(pcpConn->pcpConn); + int ret = pcp_flush(pcpConn->pcpConn); + if (ret) pcp_internal_error(pcpConn, - "ERROR: sending data to backend failed with error \"%s\"",strerror(errno)); + "ERROR: sending data to backend failed with error \"%s\"", strerror(errno)); return ret; } -int pcp_result_slot_count(PCPResultInfo* res) +int +pcp_result_slot_count(PCPResultInfo * res) { - if(res) + if (res) return res->resultSlots; return 0; } /* Returns 1 if ResultInfo has no data. 0 otherwise */ -int pcp_result_is_empty(PCPResultInfo* res) +int +pcp_result_is_empty(PCPResultInfo * res) { if (res) { @@ -1707,48 +1729,53 @@ int pcp_result_is_empty(PCPResultInfo* res) return 1; } -void *pcp_get_binary_data(const PCPResultInfo *res, unsigned int slotno) +void * +pcp_get_binary_data(const PCPResultInfo * res, unsigned int slotno) { - if(res && slotno < res->resultSlots && !res->resultSlot[slotno].isint) + if (res && slotno < res->resultSlots && !res->resultSlot[slotno].isint) { return res->resultSlot[slotno].data.ptr; } return NULL; } -int pcp_get_int_data(const PCPResultInfo *res, unsigned int slotno) +int +pcp_get_int_data(const PCPResultInfo * res, unsigned int slotno) { - if(res && slotno < res->resultSlots && res->resultSlot[slotno].isint) + if (res && slotno < res->resultSlots && res->resultSlot[slotno].isint) { return res->resultSlot[slotno].data.integer; } return 0; } -int pcp_get_data_length(const PCPResultInfo *res, unsigned int slotno) +int +pcp_get_data_length(const PCPResultInfo * res, unsigned int slotno) { - if(res && slotno < res->resultSlots) + if (res && slotno < res->resultSlots) { return res->resultSlot[slotno].datalen; } return 0; } -void pcp_free_result(PCPConnInfo* pcpConn) +void +pcp_free_result(PCPConnInfo * pcpConn) { - if(pcpConn && pcpConn->pcpResInfo) + if (pcpConn && pcpConn->pcpResInfo) { - PCPResultInfo* pcpRes = pcpConn->pcpResInfo; - int i; - for(i = 0; i< pcpRes->resultSlots; i++) + PCPResultInfo *pcpRes = pcpConn->pcpResInfo; + int i; + + for (i = 0; i < pcpRes->resultSlots; i++) { - if(pcpRes->resultSlot[i].isint) + if (pcpRes->resultSlot[i].isint) continue; - if(pcpRes->resultSlot[i].data.ptr == NULL) + if (pcpRes->resultSlot[i].data.ptr == NULL) continue; - if(pcpRes->resultSlot[i].free_func) - pcpRes->resultSlot[i].free_func(pcpConn,pcpRes->resultSlot[i].data.ptr); + if (pcpRes->resultSlot[i].free_func) + pcpRes->resultSlot[i].free_func(pcpConn, pcpRes->resultSlot[i].data.ptr); else pfree(pcpRes->resultSlot[i].data.ptr); pcpRes->resultSlot[i].data.ptr = NULL; @@ -1758,21 +1785,23 @@ void pcp_free_result(PCPConnInfo* pcpConn) } } -void pcp_free_connection(PCPConnInfo* pcpConn) +void +pcp_free_connection(PCPConnInfo * pcpConn) { - if(pcpConn) + if (pcpConn) { pcp_free_result(pcpConn); - if(pcpConn->errMsg) + if (pcpConn->errMsg) pfree(pcpConn->errMsg); - /* Should we also Disconnect it?*/ + /* Should we also Disconnect it? */ pfree(pcpConn); } } -char *pcp_get_last_error(PCPConnInfo* pcpConn) +char * +pcp_get_last_error(PCPConnInfo * pcpConn) { - if(pcpConn) + if (pcpConn) return pcpConn->errMsg; return NULL; } @@ -1784,8 +1813,8 @@ char *pcp_get_last_error(PCPConnInfo* pcpConn) static bool getPoolPassFilename(char *pgpassfile) { - char *passfile_env; - + char *passfile_env; + if ((passfile_env = getenv("PCPPASSFILE")) != NULL) { /* use the literal path from the environment, if set */ @@ -1793,7 +1822,8 @@ getPoolPassFilename(char *pgpassfile) } else { - char homedir[MAXPGPATH]; + char homedir[MAXPGPATH]; + if (!get_home_directory(homedir, sizeof(homedir))) return false; snprintf(pgpassfile, MAXPGPATH, "%s/%s", homedir, PCPPASSFILE); @@ -1803,23 +1833,23 @@ getPoolPassFilename(char *pgpassfile) /* * Get a password from the password file. Return value is malloc'd. - * format = hostname:port:username:password + * format = hostname:port:username:password */ static char * -PasswordFromFile(PCPConnInfo* pcpConn, char *hostname, char *port, char *username) +PasswordFromFile(PCPConnInfo * pcpConn, char *hostname, char *port, char *username) { - FILE *fp; - char pgpassfile[MAXPGPATH]; + FILE *fp; + char pgpassfile[MAXPGPATH]; struct stat stat_buf; #define LINELEN NAMEDATALEN*5 - char buf[LINELEN]; + char buf[LINELEN]; if (username == NULL || strlen(username) == 0) return NULL; if (hostname == NULL) hostname = DefaultHost; - else if(strcmp(hostname , UNIX_DOMAIN_PATH) == 0) + else if (strcmp(hostname, UNIX_DOMAIN_PATH) == 0) hostname = DefaultHost; if (!getPoolPassFilename(pgpassfile)) @@ -1831,43 +1861,43 @@ PasswordFromFile(PCPConnInfo* pcpConn, char *hostname, char *port, char *usernam if (!S_ISREG(stat_buf.st_mode)) { - if(pcpConn->Pfdebug) - fprintf(pcpConn->Pfdebug, "WARNING: password file \"%s\" is not a plain file\n",pgpassfile); + if (pcpConn->Pfdebug) + fprintf(pcpConn->Pfdebug, "WARNING: password file \"%s\" is not a plain file\n", pgpassfile); return NULL; } - + /* If password file is insecure, alert the user and ignore it. */ if (stat_buf.st_mode & (S_IRWXG | S_IRWXO)) { - if(pcpConn->Pfdebug) + if (pcpConn->Pfdebug) fprintf(pcpConn->Pfdebug, "WARNING: password file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n", - pgpassfile); + pgpassfile); return NULL; } fp = fopen(pgpassfile, "r"); if (fp == NULL) return NULL; - + while (!feof(fp) && !ferror(fp)) { - char *t = buf, - *ret, - *p1, - *p2; - int len; - + char *t = buf, + *ret, + *p1, + *p2; + int len; + if (fgets(buf, sizeof(buf), fp) == NULL) break; - + len = strlen(buf); if (len == 0) continue; - + /* Remove trailing newline */ if (buf[len - 1] == '\n') buf[len - 1] = 0; - + if ((t = pwdfMatchesString(t, hostname)) == NULL || (t = pwdfMatchesString(t, port)) == NULL || (t = pwdfMatchesString(t, username)) == NULL) @@ -1883,13 +1913,13 @@ PasswordFromFile(PCPConnInfo* pcpConn, char *hostname, char *port, char *usernam *p2 = *p1; } *p2 = '\0'; - + return ret; } - + fclose(fp); return NULL; - + #undef LINELEN } @@ -1901,10 +1931,10 @@ PasswordFromFile(PCPConnInfo* pcpConn, char *hostname, char *port, char *usernam static char * pwdfMatchesString(char *buf, char *token) { - char *tbuf, - *ttok; - bool bslash = false; - + char *tbuf, + *ttok; + bool bslash = false; + if (buf == NULL || token == NULL) return NULL; tbuf = buf; diff --git a/src/main/health_check.c b/src/main/health_check.c index 835970817..ecf9b348b 100644 --- a/src/main/health_check.c +++ b/src/main/health_check.c @@ -62,8 +62,8 @@ #include "auth/pool_hba.h" #include "utils/pool_stream.h" -char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ -static POOL_CONNECTION_POOL_SLOT *slot; +char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ +static POOL_CONNECTION_POOL_SLOT * slot; static volatile sig_atomic_t reload_config_request = 0; static volatile sig_atomic_t restart_request = 0; static bool establish_persistent_connection(int node); @@ -74,9 +74,9 @@ static void reload_config(void); static RETSIGTYPE health_check_timer_handler(int sig); #ifdef HEALTHCHECK_OPTS - #if HEALTHCHECK_OPTS > 0 - #define HEALTHCHECK_DEBUG - #endif +#if HEALTHCHECK_OPTS > 0 +#define HEALTHCHECK_DEBUG +#endif #endif #ifdef HEALTHCHECK_DEBUG @@ -106,11 +106,12 @@ static bool check_backend_down_request(int node); /* * health check child main loop */ -void do_health_check_child(int *node_id) +void +do_health_check_child(int *node_id) { - sigjmp_buf local_sigjmp_buf; + sigjmp_buf local_sigjmp_buf; MemoryContext HealthCheckMemoryContext; - char psbuffer[NI_MAXHOST]; + char psbuffer[NI_MAXHOST]; ereport(DEBUG1, (errmsg("I am health check process pid:%d DB node id:%d", getpid(), *node_id))); @@ -131,9 +132,9 @@ void do_health_check_child(int *node_id) signal(SIGUSR2, SIG_IGN); signal(SIGPIPE, SIG_IGN); - /* Create per loop iteration memory context */ + /* Create per loop iteration memory context */ HealthCheckMemoryContext = AllocSetContextCreate(TopMemoryContext, - "health_check_main_loop", + "health_check_main_loop", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); @@ -146,7 +147,7 @@ void do_health_check_child(int *node_id) /* Initialize per process context */ pool_init_process_context(); - if (sigsetjmp(local_sigjmp_buf, 1) != 0) + if (sigsetjmp(local_sigjmp_buf, 1) != 0) { pool_signal(SIGALRM, SIG_IGN); error_context_stack = NULL; @@ -160,7 +161,7 @@ void do_health_check_child(int *node_id) for (;;) { - MemoryContextSwitchTo(HealthCheckMemoryContext); + MemoryContextSwitchTo(HealthCheckMemoryContext); MemoryContextResetAndDeleteChildren(HealthCheckMemoryContext); CHECK_REQUEST; @@ -176,7 +177,7 @@ void do_health_check_child(int *node_id) */ else if (pool_config->health_check_params[*node_id].health_check_period > 0) { - bool result; + bool result; result = establish_persistent_connection(*node_id); @@ -194,14 +195,14 @@ void do_health_check_child(int *node_id) } else { - bool partial; + bool partial; ereport(LOG, (errmsg("health check failed on node %d (timeout:%d)", *node_id, health_check_timer_expired))); /* trigger failover */ - partial = health_check_timer_expired?false:true; - degenerate_backend_set(node_id, 1, partial?REQ_DETAIL_SWITCHOVER:0); + partial = health_check_timer_expired ? false : true; + degenerate_backend_set(node_id, 1, partial ? REQ_DETAIL_SWITCHOVER : 0); } } @@ -217,16 +218,16 @@ void do_health_check_child(int *node_id) * Establish persistent connection to backend. * Return true if connection test is done. */ -static bool establish_persistent_connection(int node) +static bool +establish_persistent_connection(int node) { BackendInfo *bkinfo; - int retry_cnt; + int retry_cnt; bkinfo = pool_get_node_info(node); /* - * If the node is already in down status or unused, - * do nothing. + * If the node is already in down status or unused, do nothing. */ if (bkinfo->backend_status == CON_UNUSED || bkinfo->backend_status == CON_DOWN) @@ -245,15 +246,14 @@ static bool establish_persistent_connection(int node) { retry_cnt = pool_config->health_check_params[node].health_check_max_retries; - char *password = get_pgpool_config_user_password(pool_config->health_check_params[node].health_check_user, - pool_config->health_check_params[node].health_check_password); + char *password = get_pgpool_config_user_password(pool_config->health_check_params[node].health_check_user, + pool_config->health_check_params[node].health_check_password); do { /* - * Set health checker timeout. we want to detect - * communication path failure much earlier before - * TCP/IP stack detects it. + * Set health checker timeout. we want to detect communication + * path failure much earlier before TCP/IP stack detects it. */ if (pool_config->health_check_params[node].health_check_timeout > 0) { @@ -268,7 +268,7 @@ static bool establish_persistent_connection(int node) bkinfo->backend_port, pool_config->health_check_params[node].health_check_database, pool_config->health_check_params[node].health_check_user, - password?password:"", false); + password ? password : "", false); if (pool_config->health_check_params[node].health_check_timeout > 0) { @@ -285,7 +285,7 @@ static bool establish_persistent_connection(int node) (errmsg("health check retrying on DB node: %d succeeded", node))); } - break; /* Success */ + break; /* Success */ } retry_cnt--; @@ -310,7 +310,8 @@ static bool establish_persistent_connection(int node) /* * Discard persistent connection to backend */ -static void discard_persistent_connection(int node) +static void +discard_persistent_connection(int node) { if (slot) { @@ -321,7 +322,7 @@ static void discard_persistent_connection(int node) static RETSIGTYPE my_signal_handler(int sig) { - int save_errno = errno; + int save_errno = errno; POOL_SETMASK(&BlockSig); @@ -350,30 +351,35 @@ static RETSIGTYPE my_signal_handler(int sig) static RETSIGTYPE reload_config_handler(int sig) { - int save_errno = errno; + int save_errno = errno; + POOL_SETMASK(&BlockSig); reload_config_request = 1; POOL_SETMASK(&UnBlockSig); errno = save_errno; } -static void reload_config(void) +static void +reload_config(void) { ereport(LOG, (errmsg("reloading config file"))); - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); if (pool_config->enable_pool_hba) load_hba(get_hba_file_name()); reload_config_request = 0; } + /* * health check timer handler */ static RETSIGTYPE health_check_timer_handler(int sig) { - int save_errno = errno; + int save_errno = errno; + POOL_SETMASK(&BlockSig); health_check_timer_expired = 1; POOL_SETMASK(&UnBlockSig); @@ -388,7 +394,7 @@ static RETSIGTYPE health_check_timer_handler(int sig) * will return true. */ -# define BACKEND_DOWN_REQUEST_FILE "backend_down_request" +#define BACKEND_DOWN_REQUEST_FILE "backend_down_request" /* * Check backend down request file with specified backend node id. If it's @@ -396,20 +402,21 @@ static RETSIGTYPE health_check_timer_handler(int sig) * prevent repeatable * failover. If it's other than "down", returns false. */ -static bool check_backend_down_request(int node) +static bool +check_backend_down_request(int node) { - static char backend_down_request_file[POOLMAXPATHLEN]; - FILE *fd; - int i; + static char backend_down_request_file[POOLMAXPATHLEN]; + FILE *fd; + int i; #define MAXLINE 128 - char linebuf[MAXLINE]; - char readbuf[MAXLINE]; - char buf[MAXLINE]; - char *writebuf; - char *p; - bool found = false; - int node_id; - char status[MAXLINE]; + char linebuf[MAXLINE]; + char readbuf[MAXLINE]; + char buf[MAXLINE]; + char *writebuf; + char *p; + bool found = false; + int node_id; + char status[MAXLINE]; if (backend_down_request_file[0] == '\0') { @@ -423,21 +430,21 @@ static bool check_backend_down_request(int node) ereport(WARNING, (errmsg("check_backend_down_request: failed to open file %s", backend_down_request_file), - errdetail("\"%s\"",strerror(errno)))); + errdetail("\"%s\"", strerror(errno)))); return false; } writebuf = NULL; - for (i=0;;i++) + for (i = 0;; i++) { - readbuf[MAXLINE-1] = '\0'; - if (fgets(readbuf, MAXLINE-1, fd) == 0) + readbuf[MAXLINE - 1] = '\0'; + if (fgets(readbuf, MAXLINE - 1, fd) == 0) break; strncpy(buf, readbuf, sizeof(buf)); - if (strlen(readbuf) > 0 && readbuf[strlen(readbuf)-1] == '\n') - buf[strlen(readbuf)-1] = '\0'; + if (strlen(readbuf) > 0 && readbuf[strlen(readbuf) - 1] == '\n') + buf[strlen(readbuf) - 1] = '\0'; p = readbuf; if (found == false) @@ -453,11 +460,11 @@ static bool check_backend_down_request(int node) if (writebuf == NULL) { - writebuf = malloc(strlen(p)+1); - memset(writebuf, 0, strlen(p)+1); + writebuf = malloc(strlen(p) + 1); + memset(writebuf, 0, strlen(p) + 1); } else - writebuf = realloc(writebuf, strlen(p)+strlen(writebuf)+1); + writebuf = realloc(writebuf, strlen(p) + strlen(writebuf) + 1); if (!writebuf) { fclose(fd); @@ -475,18 +482,18 @@ static bool check_backend_down_request(int node) if (!fd) { ereport(WARNING, - (errmsg("check_backend_down_request: failed to open file for writing %s", + (errmsg("check_backend_down_request: failed to open file for writing %s", backend_down_request_file), - errdetail("\"%s\"",strerror(errno)))); + errdetail("\"%s\"", strerror(errno)))); return false; } if (fwrite(writebuf, 1, strlen(writebuf), fd) != strlen(writebuf)) { ereport(WARNING, - (errmsg("check_backend_down_request: failed to write %s", + (errmsg("check_backend_down_request: failed to write %s", backend_down_request_file), - errdetail("\"%s\"",strerror(errno)))); + errdetail("\"%s\"", strerror(errno)))); fclose(fd); return false; } diff --git a/src/main/main.c b/src/main/main.c index 50d623833..5392dac22 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -21,7 +21,7 @@ #include "pool.h" #include "pool_config.h" #include <fcntl.h> -#include <sys/types.h> +#include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -51,37 +51,39 @@ static bool get_pool_key_filename(char *poolKeyFile); static void daemonize(void); -static char *get_pid_file_path(void); -static int read_pid_file(void); +static char *get_pid_file_path(void); +static int read_pid_file(void); static void write_pid_file(void); static void usage(void); static void show_version(void); static void stop_me(void); static void FileUnlink(int code, Datum path); -char *pcp_conf_file = NULL; /* absolute path of the pcp.conf */ -char *conf_file = NULL; /* absolute path of the pgpool.conf */ -char *hba_file = NULL; /* absolute path of the hba.conf */ -char *base_dir = NULL; /* The working dir from where pgpool was invoked from */ - -static int not_detach = 0; /* non 0 if non detach option (-n) is given */ -int stop_sig = SIGTERM; /* stopping signal default value */ -int myargc; -char **myargv; -int assert_enabled = 0; -char *pool_key = NULL; -int main(int argc, char **argv) +char *pcp_conf_file = NULL; /* absolute path of the pcp.conf */ +char *conf_file = NULL; /* absolute path of the pgpool.conf */ +char *hba_file = NULL; /* absolute path of the hba.conf */ +char *base_dir = NULL; /* The working dir from where pgpool was + * invoked from */ + +static int not_detach = 0; /* non 0 if non detach option (-n) is given */ +int stop_sig = SIGTERM; /* stopping signal default value */ +int myargc; +char **myargv; +int assert_enabled = 0; +char *pool_key = NULL; +int +main(int argc, char **argv) { - int opt; - int debug_level = 0; - int optindex; - bool discard_status = false; - bool clear_memcache_oidmaps = false; + int opt; + int debug_level = 0; + int optindex; + bool discard_status = false; + bool clear_memcache_oidmaps = false; - char pcp_conf_file_path[POOLMAXPATHLEN+1]; - char conf_file_path[POOLMAXPATHLEN+1]; - char hba_file_path[POOLMAXPATHLEN+1]; - char pool_passwd_key_file_path[POOLMAXPATHLEN+1]; + char pcp_conf_file_path[POOLMAXPATHLEN + 1]; + char conf_file_path[POOLMAXPATHLEN + 1]; + char hba_file_path[POOLMAXPATHLEN + 1]; + char pool_passwd_key_file_path[POOLMAXPATHLEN + 1]; static struct option long_options[] = { {"hba-file", required_argument, NULL, 'a'}, @@ -111,7 +113,7 @@ int main(int argc, char **argv) { switch (opt) { - case 'a': /* specify hba configuration file */ + case 'a': /* specify hba configuration file */ if (!optarg) { usage(); @@ -120,15 +122,15 @@ int main(int argc, char **argv) strlcpy(hba_file_path, optarg, sizeof(hba_file_path)); break; - case 'x': /* enable cassert */ + case 'x': /* enable cassert */ assert_enabled = 1; break; - case 'd': /* debug option */ + case 'd': /* debug option */ debug_level = 1; break; - case 'f': /* specify configuration file */ + case 'f': /* specify configuration file */ if (!optarg) { usage(); @@ -137,7 +139,7 @@ int main(int argc, char **argv) strlcpy(conf_file_path, optarg, sizeof(conf_file_path)); break; - case 'F': /* specify PCP password file */ + case 'F': /* specify PCP password file */ if (!optarg) { usage(); @@ -146,7 +148,8 @@ int main(int argc, char **argv) strlcpy(pcp_conf_file_path, optarg, sizeof(pcp_conf_file_path)); break; - case 'k': /* specify key file for decrypt pool_password entries */ + case 'k': /* specify key file for decrypt pool_password + * entries */ if (!optarg) { usage(); @@ -160,18 +163,18 @@ int main(int argc, char **argv) exit(0); break; - case 'm': /* stop mode */ + case 'm': /* stop mode */ if (!optarg) { usage(); exit(1); } if (*optarg == 's' || !strcmp("smart", optarg)) - stop_sig = SIGTERM; /* smart shutdown */ + stop_sig = SIGTERM; /* smart shutdown */ else if (*optarg == 'f' || !strcmp("fast", optarg)) - stop_sig = SIGINT; /* fast shutdown */ + stop_sig = SIGINT; /* fast shutdown */ else if (*optarg == 'i' || !strcmp("immediate", optarg)) - stop_sig = SIGQUIT; /* immediate shutdown */ + stop_sig = SIGQUIT; /* immediate shutdown */ else { usage(); @@ -179,15 +182,15 @@ int main(int argc, char **argv) } break; - case 'n': /* no detaching control ttys */ + case 'n': /* no detaching control ttys */ not_detach = 1; break; - case 'D': /* discard pgpool_status */ + case 'D': /* discard pgpool_status */ discard_status = true; break; - case 'C': /* discard caches in memcached */ + case 'C': /* discard caches in memcached */ clear_memcache_oidmaps = true; break; @@ -202,24 +205,24 @@ int main(int argc, char **argv) } #ifdef NOT_USED -//#ifdef USE_SSL -// /* global ssl init */ -//#if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined (LIBRESSL_VERSION_NUMBER)) -// OPENSSL_init_ssl(0, NULL); -//#else -// SSL_library_init(); -//#endif -// SSL_load_error_strings(); -//#endif /* USE_SSL */ +/* #ifdef USE_SSL */ + /* /* global ssl init */ */ +/* #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined (LIBRESSL_VERSION_NUMBER)) */ +/* OPENSSL_init_ssl(0, NULL); */ +/* #else */ +/* SSL_library_init(); */ +/* #endif */ +/* SSL_load_error_strings(); */ + /* #endif /* USE_SSL */ */ #endif - myargv = save_ps_display_args(myargc, myargv); + myargv = save_ps_display_args(myargc, myargv); /* create MemoryContexts */ MemoryContextInit(); /* load the CWD before it is changed */ base_dir = get_current_working_dir(); - /* convert all the paths to absolute paths*/ + /* convert all the paths to absolute paths */ conf_file = make_absolute_path(conf_file_path, base_dir); pcp_conf_file = make_absolute_path(pcp_conf_file_path, base_dir); hba_file = make_absolute_path(hba_file_path, base_dir); @@ -231,36 +234,37 @@ int main(int argc, char **argv) pool_get_config(conf_file, CFGCXT_INIT); /* - * Override debug level - * if command line -d arg is given adjust the log_min_message config variable + * Override debug level if command line -d arg is given adjust the + * log_min_message config variable */ - if(debug_level > 0 && pool_config->log_min_messages > DEBUG1) - set_one_config_option("log_min_messages", "DEBUG1",CFGCXT_INIT, PGC_S_ARGV, INFO); + if (debug_level > 0 && pool_config->log_min_messages > DEBUG1) + set_one_config_option("log_min_messages", "DEBUG1", CFGCXT_INIT, PGC_S_ARGV, INFO); /* - * If a non-switch argument remains, then it should be either "reload" or "stop". + * If a non-switch argument remains, then it should be either "reload" or + * "stop". */ if (optind == (argc - 1)) { if (!strcmp(argv[optind], "reload")) { - pid_t pid; + pid_t pid; - pid = read_pid_file(); - if (pid < 0) - { - ereport(FATAL, + pid = read_pid_file(); + if (pid < 0) + { + ereport(FATAL, (return_code(1), - errmsg("could not read pid file"))); - } + errmsg("could not read pid file"))); + } - if (kill(pid, SIGHUP) == -1) - { - ereport(FATAL, + if (kill(pid, SIGHUP) == -1) + { + ereport(FATAL, (return_code(1), errmsg("could not reload configuration file pid: %d. reason: %s", pid, strerror(errno)))); - } - exit(0); + } + exit(0); } if (!strcmp(argv[optind], "stop")) { @@ -273,24 +277,28 @@ int main(int argc, char **argv) exit(1); } } + /* - * else if no non-switch argument remains, then it should be a start request + * else if no non-switch argument remains, then it should be a start + * request */ else if (optind == argc) { - int pid = read_pid_file(); + int pid = read_pid_file(); + if (pid > 0) { if (kill(pid, 0) == 0) { ereport(FATAL, - (errmsg("pid file found. is another pgpool(%d) is running?\n", pid))); + (errmsg("pid file found. is another pgpool(%d) is running?\n", pid))); } else ereport(NOTICE, - (errmsg("pid file found but it seems bogus. Trying to start pgpool anyway...\n"))); + (errmsg("pid file found but it seems bogus. Trying to start pgpool anyway...\n"))); } } + /* * otherwise an error... */ @@ -304,12 +312,13 @@ int main(int argc, char **argv) load_hba(hba_file); #ifdef USE_SSL + /* * If ssl is enabled, initialize the SSL context */ if (pool_config->ssl) SSL_ServerSide_init(); -#endif /* USE_SSL */ +#endif /* USE_SSL */ /* check effective user id for watchdog */ /* watchdog must be started under the privileged user */ @@ -329,16 +338,16 @@ int main(int argc, char **argv) write_pid_file(); else daemonize(); + /* - * Locate pool_passwd - * The default file name "pool_passwd" can be changed by setting - * pgpool.conf's "pool_passwd" directive. + * Locate pool_passwd The default file name "pool_passwd" can be changed + * by setting pgpool.conf's "pool_passwd" directive. */ if (strcmp("", pool_config->pool_passwd)) { - char pool_passwd[POOLMAXPATHLEN+1]; - char dirnamebuf[POOLMAXPATHLEN+1]; - char *dirp; + char pool_passwd[POOLMAXPATHLEN + 1]; + char dirnamebuf[POOLMAXPATHLEN + 1]; + char *dirp; strlcpy(dirnamebuf, conf_file, sizeof(dirnamebuf)); dirp = dirname(dirnamebuf); @@ -349,24 +358,28 @@ int main(int argc, char **argv) pool_semaphore_create(MAX_NUM_SEMAPHORES); - PgpoolMain(discard_status, clear_memcache_oidmaps); /* this is an infinate loop */ + PgpoolMain(discard_status, clear_memcache_oidmaps); /* this is an infinate + * loop */ exit(0); } -static void show_version(void) +static void +show_version(void) { - fprintf(stderr, "%s version %s (%s)\n", PACKAGE, VERSION, PGPOOLVERSION); + fprintf(stderr, "%s version %s (%s)\n", PACKAGE, VERSION, PGPOOLVERSION); } -static void usage(void) +static void +usage(void) { - char homedir[POOLMAXPATHLEN]; + char homedir[POOLMAXPATHLEN]; + if (!get_home_directory(homedir, sizeof(homedir))) - strncpy(homedir,"USER-HOME-DIR",POOLMAXPATHLEN); + strncpy(homedir, "USER-HOME-DIR", POOLMAXPATHLEN); - fprintf(stderr, "%s version %s (%s),\n", PACKAGE, VERSION, PGPOOLVERSION); + fprintf(stderr, "%s version %s (%s),\n", PACKAGE, VERSION, PGPOOLVERSION); fprintf(stderr, " A generic connection pool/replication/load balance server for PostgreSQL\n\n"); fprintf(stderr, "Usage:\n"); fprintf(stderr, " pgpool [ -c] [ -f CONFIG_FILE ] [ -F PCP_CONFIG_FILE ] [ -a HBA_CONFIG_FILE ]\n"); @@ -377,17 +390,17 @@ static void usage(void) fprintf(stderr, "Common options:\n"); fprintf(stderr, " -a, --hba-file=HBA_CONFIG_FILE\n"); fprintf(stderr, " Set the path to the pool_hba.conf configuration file\n"); - fprintf(stderr, " (default: %s/%s)\n",DEFAULT_CONFIGDIR, HBA_CONF_FILE_NAME); + fprintf(stderr, " (default: %s/%s)\n", DEFAULT_CONFIGDIR, HBA_CONF_FILE_NAME); fprintf(stderr, " -f, --config-file=CONFIG_FILE\n"); fprintf(stderr, " Set the path to the pgpool.conf configuration file\n"); - fprintf(stderr, " (default: %s/%s)\n",DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); + fprintf(stderr, " (default: %s/%s)\n", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); fprintf(stderr, " -k, --key-file=KEY_FILE\n"); fprintf(stderr, " Set the path to the pgpool key file\n"); - fprintf(stderr, " (default: %s/%s)\n",homedir, POOLKEYFILE); - fprintf(stderr, " can be over ridden by %s environment variable\n",POOLKEYFILEENV); + fprintf(stderr, " (default: %s/%s)\n", homedir, POOLKEYFILE); + fprintf(stderr, " can be over ridden by %s environment variable\n", POOLKEYFILEENV); fprintf(stderr, " -F, --pcp-file=PCP_CONFIG_FILE\n"); fprintf(stderr, " Set the path to the pcp.conf configuration file\n"); - fprintf(stderr, " (default: %s/%s)\n",DEFAULT_CONFIGDIR, PCP_PASSWD_FILE_NAME); + fprintf(stderr, " (default: %s/%s)\n", DEFAULT_CONFIGDIR, PCP_PASSWD_FILE_NAME); fprintf(stderr, " -h, --help Print this help\n\n"); fprintf(stderr, "Start options:\n"); fprintf(stderr, " -C, --clear-oidmaps Clear query cache oidmaps when memqcache_method is memcached\n"); @@ -408,7 +421,7 @@ static void usage(void) static bool get_pool_key_filename(char *poolKeyFile) { - char *passfile_env; + char *passfile_env; if ((passfile_env = getenv(POOLKEYFILEENV)) != NULL) { @@ -417,7 +430,8 @@ get_pool_key_filename(char *poolKeyFile) } else { - char homedir[POOLMAXPATHLEN]; + char homedir[POOLMAXPATHLEN]; + if (!get_home_directory(homedir, sizeof(homedir))) return false; snprintf(poolKeyFile, POOLMAXPATHLEN, "%s/%s", homedir, POOLKEYFILE); @@ -426,14 +440,17 @@ get_pool_key_filename(char *poolKeyFile) } -char *get_pool_key(void) +char * +get_pool_key(void) { return pool_key; } + /* * detach control ttys */ -static void daemonize(void) +static void +daemonize(void) { int i; pid_t pid; @@ -443,11 +460,11 @@ static void daemonize(void) if (pid == (pid_t) -1) { ereport(FATAL, - (errmsg("could not daemonize the pgpool-II"), - errdetail("fork() system call failed with reason: \"%s\"", strerror(errno) ))); + (errmsg("could not daemonize the pgpool-II"), + errdetail("fork() system call failed with reason: \"%s\"", strerror(errno)))); } else if (pid > 0) - { /* parent */ + { /* parent */ exit(0); } @@ -455,24 +472,24 @@ static void daemonize(void) if (setsid() < 0) { ereport(FATAL, - (errmsg("could not daemonize the pgpool-II"), - errdetail("setsid() system call failed with reason: \"%s\"", strerror(errno) ))); + (errmsg("could not daemonize the pgpool-II"), + errdetail("setsid() system call failed with reason: \"%s\"", strerror(errno)))); } #endif mypid = getpid(); write_pid_file(); - if(chdir("/")) + if (chdir("/")) ereport(WARNING, - (errmsg("change directory failed"), - errdetail("chdir() system call failed with reason: \"%s\"", strerror(errno) ))); + (errmsg("change directory failed"), + errdetail("chdir() system call failed with reason: \"%s\"", strerror(errno)))); /* redirect stdin, stdout and stderr to /dev/null */ i = open("/dev/null", O_RDWR); - if(i < 0) + if (i < 0) { ereport(WARNING, - (errmsg("failed to open \"/dev/null\", open() failed with error \"%s\"", strerror(errno)))); + (errmsg("failed to open \"/dev/null\", open() failed with error \"%s\"", strerror(errno)))); } else { @@ -488,34 +505,35 @@ static void daemonize(void) } /* close other file descriptors */ - fdlimit = sysconf(_SC_OPEN_MAX); - for (i = 3; i < fdlimit; i++) + fdlimit = sysconf(_SC_OPEN_MAX); + for (i = 3; i < fdlimit; i++) close(i); } /* * stop myself */ -static void stop_me(void) +static void +stop_me(void) { - pid_t pid; - char *pid_file; + pid_t pid; + char *pid_file; pid = read_pid_file(); if (pid < 0) { ereport(FATAL, - (errmsg("could not read pid file"))); + (errmsg("could not read pid file"))); } if (kill(pid, stop_sig) == -1) { ereport(FATAL, - (errmsg("could not stop process with pid: %d", pid), - errdetail("\"%s\"", strerror(errno)))); + (errmsg("could not stop process with pid: %d", pid), + errdetail("\"%s\"", strerror(errno)))); } ereport(LOG, - (errmsg ("stop request sent to pgpool. waiting for termination..."))); + (errmsg("stop request sent to pgpool. waiting for termination..."))); while (kill(pid, 0) == 0) { @@ -532,29 +550,31 @@ static void stop_me(void) * The function returns the palloc'd copy of pid_file_path, * caller must free it after use */ -static char *get_pid_file_path(void) +static char * +get_pid_file_path(void) { - char *new = NULL; + char *new = NULL; + if (!is_absolute_path(pool_config->pid_file_name)) { /* - * some implementations of dirname() may modify the - * string argument passed to it, so do not use the original - * conf_file as an argument + * some implementations of dirname() may modify the string argument + * passed to it, so do not use the original conf_file as an argument */ - char *conf_file_copy = pstrdup(conf_file); - char *conf_dir = dirname(conf_file_copy); - size_t path_size; + char *conf_file_copy = pstrdup(conf_file); + char *conf_dir = dirname(conf_file_copy); + size_t path_size; + if (conf_dir == NULL) { ereport(LOG, (errmsg("failed to get the dirname of pid file:\"%s\". reason: %s", - pool_config->pid_file_name, strerror(errno)))); + pool_config->pid_file_name, strerror(errno)))); return NULL; } path_size = strlen(conf_dir) + strlen(pool_config->pid_file_name) + 1 + 1; new = palloc(path_size); - snprintf(new, path_size, "%s/%s",conf_dir, pool_config->pid_file_name); + snprintf(new, path_size, "%s/%s", conf_dir, pool_config->pid_file_name); ereport(DEBUG1, (errmsg("pid file location is \"%s\"", @@ -573,12 +593,13 @@ static char *get_pid_file_path(void) /* * read the pid file */ -static int read_pid_file(void) +static int +read_pid_file(void) { - int fd; - int readlen; - char pidbuf[128]; - char *pid_file = get_pid_file_path(); + int fd; + int readlen; + char pidbuf[128]; + char *pid_file = get_pid_file_path(); if (pid_file == NULL) { @@ -598,69 +619,70 @@ static int read_pid_file(void) close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("could not read pid file as \"%s\". reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not read pid file as \"%s\". reason: %s", + pool_config->pid_file_name, strerror(errno)))); } else if (readlen == 0) { close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("EOF detected while reading pid file \"%s\". reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("EOF detected while reading pid file \"%s\". reason: %s", + pool_config->pid_file_name, strerror(errno)))); } pfree(pid_file); close(fd); - return(atoi(pidbuf)); + return (atoi(pidbuf)); } /* * write the pid file */ -static void write_pid_file(void) +static void +write_pid_file(void) { - int fd; - char pidbuf[128]; - char *pid_file = get_pid_file_path(); + int fd; + char pidbuf[128]; + char *pid_file = get_pid_file_path(); if (pid_file == NULL) { ereport(FATAL, (errmsg("failed to write pid file"), errdetail("failed to get pid file path from \"%s\"", - pool_config->pid_file_name))); + pool_config->pid_file_name))); } - fd = open(pid_file, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); + fd = open(pid_file, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); if (fd == -1) { ereport(FATAL, - (errmsg("could not open pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not open pid file as %s. reason: %s", + pool_config->pid_file_name, strerror(errno)))); } - snprintf(pidbuf, sizeof(pidbuf), "%d", (int)getpid()); - if (write(fd, pidbuf, strlen(pidbuf)+1) == -1) + snprintf(pidbuf, sizeof(pidbuf), "%d", (int) getpid()); + if (write(fd, pidbuf, strlen(pidbuf) + 1) == -1) { close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("could not write pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not write pid file as %s. reason: %s", + pool_config->pid_file_name, strerror(errno)))); } if (fsync(fd) == -1) { close(fd); pfree(pid_file); ereport(FATAL, - (errmsg("could not fsync pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not fsync pid file as %s. reason: %s", + pool_config->pid_file_name, strerror(errno)))); } if (close(fd) == -1) { pfree(pid_file); ereport(FATAL, - (errmsg("could not close pid file as %s. reason: %s", - pool_config->pid_file_name, strerror(errno)))); + (errmsg("could not close pid file as %s. reason: %s", + pool_config->pid_file_name, strerror(errno)))); } /* register the call back to delete the pid file at system exit */ on_proc_exit(FileUnlink, (Datum) pid_file); @@ -669,7 +691,8 @@ static void write_pid_file(void) /* * get_config_file_name: return full path of pgpool.conf. */ -char *get_config_file_name(void) +char * +get_config_file_name(void) { return conf_file; } @@ -677,21 +700,28 @@ char *get_config_file_name(void) /* * get_hba_file_name: return full path of pool_hba.conf. */ -char *get_hba_file_name(void) +char * +get_hba_file_name(void) { return hba_file; } + /* * Call back function to unlink the file */ -static void FileUnlink(int code, Datum path) +static void +FileUnlink(int code, Datum path) { - char* filePath = (char*)path; - if (unlink(filePath) == 0) return; - /* - * We are already exiting the system just produce a log entry to report an error + char *filePath = (char *) path; + + if (unlink(filePath) == 0) + return; + + /* + * We are already exiting the system just produce a log entry to report an + * error */ ereport(LOG, - (errmsg("unlink failed for file at path \"%s\"", filePath), - errdetail("\"%s\"", strerror(errno)))); + (errmsg("unlink failed for file at path \"%s\"", filePath), + errdetail("\"%s\"", strerror(errno)))); } diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c index 7329f0fb1..d670f2f3d 100644 --- a/src/main/pgpool_main.c +++ b/src/main/pgpool_main.c @@ -68,18 +68,22 @@ typedef enum { SIG_FAILOVER_INTERRUPT, /* signal main to start failover */ - SIG_WATCHDOG_STATE_CHANGED, /* notify main about local watchdog node state changed */ - SIG_BACKEND_SYNC_REQUIRED, /* notify main about local backend state sync required */ - SIG_WATCHDOG_QUORUM_CHANGED,/* notify main about cluster quorum change of watchdog cluster */ - SIG_INFORM_QURANTINE_NODES, /* notify main about send degenerate requests for all quarantine nodes */ + SIG_WATCHDOG_STATE_CHANGED, /* notify main about local watchdog node state + * changed */ + SIG_BACKEND_SYNC_REQUIRED, /* notify main about local backend state sync + * required */ + SIG_WATCHDOG_QUORUM_CHANGED, /* notify main about cluster quorum change + * of watchdog cluster */ + SIG_INFORM_QURANTINE_NODES, /* notify main about send degenerate requests + * for all quarantine nodes */ MAX_INTERUPTS /* Must be last! */ -} User1SignalReason; +} User1SignalReason; typedef struct User1SignalSlot { - sig_atomic_t signalFlags[MAX_INTERUPTS]; -} User1SignalSlot; + sig_atomic_t signalFlags[MAX_INTERUPTS]; +} User1SignalSlot; /* * Process pending signal actions. @@ -115,18 +119,18 @@ static void FileUnlink(int code, Datum path); static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file); static pid_t fork_a_child(int *fds, int id); static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params); -static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp); -static int create_inet_domain_socket(const char *hostname, const int port); +static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp); +static int create_inet_domain_socket(const char *hostname, const int port); static int *create_inet_domain_sockets(const char *hostname, const int port); static void failover(void); static bool check_all_backend_down(void); static void reaper(void); static void wakeup_children(void); static void reload_config(void); -static int pool_pause(struct timeval *timeout); +static int pool_pause(struct timeval *timeout); static void kill_all_children(int sig); static pid_t fork_follow_child(int old_master, int new_primary, int old_primary); -static int read_status_file(bool discard_status); +static int read_status_file(bool discard_status); static RETSIGTYPE exit_handler(int sig); static RETSIGTYPE reap_handler(int sig); static RETSIGTYPE sigusr1_handler(int sig); @@ -136,22 +140,23 @@ static RETSIGTYPE wakeup_handler(int sig); static void initialize_shared_mem_objects(bool clear_memcache_oidmaps); static int trigger_failover_command(int node, const char *command_line, - int old_master, int new_master, int old_primary); -static int find_primary_node(void); -static int find_primary_node_repeatedly(void); + int old_master, int new_master, int old_primary); +static int find_primary_node(void); +static int find_primary_node_repeatedly(void); static void terminate_all_childrens(); static void system_will_go_down(int code, Datum arg); -static char* process_name_from_pid(pid_t pid); +static char *process_name_from_pid(pid_t pid); static void sync_backend_from_watchdog(void); static void update_backend_quarantine_status(void); static void degenerate_all_quarantine_nodes(void); -static int get_server_version(POOL_CONNECTION_POOL_SLOT **slots, int node_id); +static int get_server_version(POOL_CONNECTION_POOL_SLOT * *slots, int node_id); static void get_info_from_conninfo(char *conninfo, char *host, char *port); -static struct sockaddr_un un_addr; /* unix domain socket path */ -static struct sockaddr_un pcp_un_addr; /* unix domain socket path for PCP */ -ProcessInfo *process_info = NULL; /* Per child info table on shmem */ -volatile User1SignalSlot *user1SignalSlot = NULL;/* User 1 signal slot on shmem */ +static struct sockaddr_un un_addr; /* unix domain socket path */ +static struct sockaddr_un pcp_un_addr; /* unix domain socket path for PCP */ +ProcessInfo *process_info = NULL; /* Per child info table on shmem */ +volatile User1SignalSlot *user1SignalSlot = NULL; /* User 1 signal slot on + * shmem */ struct timeval random_start_time; /* @@ -171,46 +176,50 @@ BACKEND_STATUS private_backend_status[MAX_NUM_BACKENDS]; */ ConnectionInfo *con_info; -static int *fds; /* listening file descriptors (UNIX socket, inet domain sockets) */ +static int *fds; /* listening file descriptors (UNIX socket, + * inet domain sockets) */ -static int pcp_unix_fd; /* unix domain socket fd for PCP (not used) */ -static int pcp_inet_fd; /* inet domain socket fd for PCP */ -extern char *pcp_conf_file; /* path for pcp.conf */ +static int pcp_unix_fd; /* unix domain socket fd for PCP (not used) */ +static int pcp_inet_fd; /* inet domain socket fd for PCP */ +extern char *pcp_conf_file; /* path for pcp.conf */ extern char *conf_file; extern char *hba_file; -static int exiting = 0; /* non 0 if I'm exiting */ -static int switching = 0; /* non 0 if I'm failing over or degenerating */ +static int exiting = 0; /* non 0 if I'm exiting */ +static int switching = 0; /* non 0 if I'm failing over or degenerating */ -POOL_REQUEST_INFO *Req_info; /* request info area in shared memory */ -volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */ +POOL_REQUEST_INFO *Req_info; /* request info area in shared memory */ +volatile sig_atomic_t *InRecovery; /* non 0 if recovery is started */ volatile sig_atomic_t reload_config_request = 0; static volatile sig_atomic_t sigusr1_request = 0; static volatile sig_atomic_t sigchld_request = 0; static volatile sig_atomic_t wakeup_request = 0; -static int pipe_fds[2]; /* for delivering signals */ +static int pipe_fds[2]; /* for delivering signals */ -int my_proc_id; +int my_proc_id; -static BackendStatusRecord backend_rec; /* Backend status record */ +static BackendStatusRecord backend_rec; /* Backend status record */ -static pid_t worker_pid = 0; /* pid of worker process */ -static pid_t follow_pid = 0; /* pid for child process handling follow command */ -static pid_t pcp_pid = 0; /* pid for child process handling PCP */ -static pid_t watchdog_pid = 0; /* pid for watchdog child process */ -static pid_t wd_lifecheck_pid = 0; /* pid for child process handling watchdog lifecheck */ +static pid_t worker_pid = 0; /* pid of worker process */ +static pid_t follow_pid = 0; /* pid for child process handling follow + * command */ +static pid_t pcp_pid = 0; /* pid for child process handling PCP */ +static pid_t watchdog_pid = 0; /* pid for watchdog child process */ +static pid_t wd_lifecheck_pid = 0; /* pid for child process handling watchdog + * lifecheck */ -BACKEND_STATUS* my_backend_status[MAX_NUM_BACKENDS]; /* Backend status buffer */ -int my_master_node_id; /* Master node id buffer */ +BACKEND_STATUS *my_backend_status[MAX_NUM_BACKENDS]; /* Backend status buffer */ +int my_master_node_id; /* Master node id buffer */ /* * pgpool main program */ -int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) +int +PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) { - int i; + int i; sigjmp_buf local_sigjmp_buf; @@ -235,7 +244,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) /* * install the call back for preparation of system exit */ - on_system_exit(system_will_go_down, (Datum)NULL); + on_system_exit(system_will_go_down, (Datum) NULL); /* set unix domain socket path for connections to pgpool */ snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/.s.PGSQL.%d", @@ -258,34 +267,35 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) initialize_shared_mem_objects(clear_memcache_oidmaps); if (pool_config->use_watchdog) { - sigset_t mask; + sigset_t mask; + wakeup_request = 0; - /* Watchdog process fires SIGUSR2 once in stable state, - * so install the SIGUSR2 handler first up. In addition, - * when wathcodg fails to start with FATAL, the process - * exits and SIGCHLD is fired, so SIGCHLD handelr is also - * needed. - * Finally, we also need to set the SIGUSR1 handler for the - * failover requests from other watchdog nodes. - * In case a request arrives at the same time when the - * watchdog has just been initialized. + /* + * Watchdog process fires SIGUSR2 once in stable state, so install the + * SIGUSR2 handler first up. In addition, when wathcodg fails to start + * with FATAL, the process exits and SIGCHLD is fired, so SIGCHLD + * handelr is also needed. Finally, we also need to set the SIGUSR1 + * handler for the failover requests from other watchdog nodes. In + * case a request arrives at the same time when the watchdog has just + * been initialized. */ pool_signal(SIGUSR2, wakeup_handler); pool_signal(SIGCHLD, reap_handler); pool_signal(SIGUSR1, sigusr1_handler); /* - * okay as we need to wait until watchdog is in stable state - * so only wait for SIGUSR1, SIGCHLD, and signals those are - * necessary to make sure we respond to user requests of shutdown - * if it arrives while we are in waiting state. + * okay as we need to wait until watchdog is in stable state so only + * wait for SIGUSR1, SIGCHLD, and signals those are necessary to make + * sure we respond to user requests of shutdown if it arrives while we + * are in waiting state. * * Note that SIGUSR1 does not need to be in the wait signal list, - * although it's signal handler is already installed, but even if - * the SIGUSR1 arrives while watchdog is initializing we will continue - * with our normal initialization and will process the failover request - * once our backend status will be synchronized across the cluster + * although it's signal handler is already installed, but even if the + * SIGUSR1 arrives while watchdog is initializing we will continue + * with our normal initialization and will process the failover + * request once our backend status will be synchronized across the + * cluster */ sigfillset(&mask); sigdelset(&mask, SIGUSR1); @@ -294,8 +304,8 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) sigdelset(&mask, SIGINT); sigdelset(&mask, SIGQUIT); watchdog_pid = initialize_watchdog(); - ereport (LOG, - (errmsg("waiting for watchdog to initialize"))); + ereport(LOG, + (errmsg("waiting for watchdog to initialize"))); while (sigusr1_request == 0 && sigchld_request == 0) { sigsuspend(&mask); @@ -308,8 +318,9 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) reaper(); } - ereport (LOG, - (errmsg("watchdog process is initialized"))); + ereport(LOG, + (errmsg("watchdog process is initialized"))); + /* * initialize the lifecheck process */ @@ -329,15 +340,16 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) /* create inet domain socket if any */ if (pool_config->listen_addresses[0]) { - int *inet_fds, *walk; - int n = 1; + int *inet_fds, + *walk; + int n = 1; inet_fds = create_inet_domain_sockets(pool_config->listen_addresses, pool_config->port); for (walk = inet_fds; *walk != -1; walk++) n++; - fds = realloc(fds, sizeof(int) * (n+1)); + fds = realloc(fds, sizeof(int) * (n + 1)); if (fds == NULL) ereport(FATAL, (errmsg("failed to allocate memory in startup process"))); @@ -345,7 +357,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) n = 1; for (walk = inet_fds; *walk != -1; walk++) { - fds[n] = inet_fds[n-1]; + fds[n] = inet_fds[n - 1]; n++; } fds[n] = -1; @@ -354,14 +366,14 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) /* - * We need to block signal here. Otherwise child might send some - * signals, for example SIGUSR1(fail over). Children will inherit - * signal blocking but they do unblock signals at the very beginning - * of process. So this is harmless. + * We need to block signal here. Otherwise child might send some signals, + * for example SIGUSR1(fail over). Children will inherit signal blocking + * but they do unblock signals at the very beginning of process. So this + * is harmless. */ POOL_SETMASK(&BlockSig); /* fork the children */ - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { process_info[i].pid = fork_a_child(fds, i); process_info[i].start_time = time(NULL); @@ -381,7 +393,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) if (pipe(pipe_fds) < 0) { ereport(FATAL, - (errmsg("failed to create pipe"))); + (errmsg("failed to create pipe"))); } MemoryContextSwitchTo(TopMemoryContext); @@ -398,7 +410,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) /* fork a child for PCP handling */ pcp_unix_fd = create_unix_domain_socket(pcp_un_addr); /* Add onproc exit to clean up the unix domain socket at exit */ - on_proc_exit(FileUnlink, (Datum)pcp_un_addr.sun_path); + on_proc_exit(FileUnlink, (Datum) pcp_un_addr.sun_path); if (pool_config->pcp_listen_addresses[0]) { @@ -410,7 +422,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) worker_pid = worker_fork_a_child(PT_WORKER, do_worker_child, NULL); /* Fork health check process */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) health_check_pids[i] = worker_fork_a_child(PT_HEALTH_CHECK, do_health_check_child, &i); @@ -431,7 +443,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) PG_exception_stack = &local_sigjmp_buf; /* Create or write status file */ - (void)write_status_file(); + (void) write_status_file(); /* This is the main loop */ for (;;) @@ -444,20 +456,23 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) */ if (first) { - int i; - int n; + int i; + int n; POOL_NODE_STATUS *node_status = pool_get_node_status(); ereport(LOG, (errmsg("%s successfully started. version %s (%s)", PACKAGE, VERSION, PGPOOLVERSION))); - /* Very early stage node checking. It is assumed that find_primary_node got called. */ + /* + * Very early stage node checking. It is assumed that + * find_primary_node got called. + */ if (STREAM) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { ereport(LOG, - (errmsg("node status[%d]: %d", i, node_status[i]))); + (errmsg("node status[%d]: %d", i, node_status[i]))); if (node_status[i] == POOL_NODE_STATUS_INVALID) { @@ -466,7 +481,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) if (pool_config->detach_false_primary) { n = i; - degenerate_backend_set(&n, 1, REQ_DETAIL_SWITCHOVER|REQ_DETAIL_CONFIRMED); + degenerate_backend_set(&n, 1, REQ_DETAIL_SWITCHOVER | REQ_DETAIL_CONFIRMED); } } } @@ -477,7 +492,7 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) processState = SLEEPING; for (;;) { - int r; + int r; struct timeval t = {3, 0}; POOL_SETMASK(&UnBlockSig); @@ -495,24 +510,24 @@ int PgpoolMain(bool discard_status, bool clear_memcache_oidmaps) * This function enqueues the failover/failback requests, and fires the failover() if the function * is not already executing */ -bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, int count, unsigned char flags) +bool +register_node_operation_request(POOL_REQUEST_KIND kind, int *node_id_set, int count, unsigned char flags) { - bool failover_in_progress; + bool failover_in_progress; pool_sigset_t oldmask; - int index; + int index; /* - * if the queue is already full - * what to do? + * if the queue is already full what to do? */ - if((Req_info->request_queue_tail - MAX_REQUEST_QUEUE_SIZE) == Req_info->request_queue_head) + if ((Req_info->request_queue_tail - MAX_REQUEST_QUEUE_SIZE) == Req_info->request_queue_head) { return false; } POOL_SETMASK2(&BlockSig, &oldmask); pool_semaphore_lock(REQUEST_INFO_SEM); - if((Req_info->request_queue_tail - MAX_REQUEST_QUEUE_SIZE) == Req_info->request_queue_head) + if ((Req_info->request_queue_tail - MAX_REQUEST_QUEUE_SIZE) == Req_info->request_queue_head) { pool_semaphore_unlock(REQUEST_INFO_SEM); return false; @@ -523,16 +538,16 @@ bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, i Req_info->request[index].request_details = flags; - if(count > 0) + if (count > 0) memcpy(Req_info->request[index].node_id, node_id_set, (sizeof(int) * count)); Req_info->request[index].count = count; failover_in_progress = Req_info->switching; pool_semaphore_unlock(REQUEST_INFO_SEM); POOL_SETMASK(&oldmask); - if(failover_in_progress == false) + if (failover_in_progress == false) { - if(processType == PT_MAIN) + if (processType == PT_MAIN) failover(); else signal_user1_to_parent_with_reason(SIG_FAILOVER_INTERRUPT); @@ -541,25 +556,30 @@ bool register_node_operation_request(POOL_REQUEST_KIND kind, int* node_id_set, i return true; } -void register_watchdog_quorum_change_interupt(void) +void +register_watchdog_quorum_change_interupt(void) { signal_user1_to_parent_with_reason(SIG_WATCHDOG_QUORUM_CHANGED); } -void register_watchdog_state_change_interupt(void) +void +register_watchdog_state_change_interupt(void) { signal_user1_to_parent_with_reason(SIG_WATCHDOG_STATE_CHANGED); } -void register_backend_state_sync_req_interupt(void) +void +register_backend_state_sync_req_interupt(void) { signal_user1_to_parent_with_reason(SIG_BACKEND_SYNC_REQUIRED); } -void register_inform_quarantine_nodes_req(void) +void +register_inform_quarantine_nodes_req(void) { signal_user1_to_parent_with_reason(SIG_INFORM_QURANTINE_NODES); } -static void signal_user1_to_parent_with_reason(User1SignalReason reason) +static void +signal_user1_to_parent_with_reason(User1SignalReason reason) { user1SignalSlot->signalFlags[reason] = true; pool_signal_parent(SIGUSR1); @@ -568,9 +588,10 @@ static void signal_user1_to_parent_with_reason(User1SignalReason reason) /* * fork a child for PCP */ -static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file) +static pid_t +pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file) { - pid_t pid; + pid_t pid; pid = fork(); @@ -593,7 +614,7 @@ static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file) else if (pid == -1) { ereport(FATAL, - (errmsg("fork() failed. reason: %s", strerror(errno)))); + (errmsg("fork() failed. reason: %s", strerror(errno)))); } return pid; @@ -602,9 +623,10 @@ static pid_t pcp_fork_a_child(int unix_fd, int inet_fd, char *pcp_conf_file) /* * fork a child */ -static pid_t fork_a_child(int *fds, int id) +static pid_t +fork_a_child(int *fds, int id) { - pid_t pid; + pid_t pid; pid = fork(); @@ -612,13 +634,13 @@ static pid_t fork_a_child(int *fds, int id) { on_exit_reset(); - /* Before we unconditionally closed pipe_fds[0] and pipe_fds[1] - * here, which is apparently wrong since in the start up of - * pgpool, pipe(2) is not called yet and it mistakenly closes - * fd 0. Now we check the fd > 0 before close(), expecting - * pipe returns fds greater than 0. Note that we cannot - * unconditionally remove close(2) calls since fork_a_child() - * may be called *after* pgpool starting up. + /* + * Before we unconditionally closed pipe_fds[0] and pipe_fds[1] here, + * which is apparently wrong since in the start up of pgpool, pipe(2) + * is not called yet and it mistakenly closes fd 0. Now we check the + * fd > 0 before close(), expecting pipe returns fds greater than 0. + * Note that we cannot unconditionally remove close(2) calls since + * fork_a_child() may be called *after* pgpool starting up. */ if (pipe_fds[0] > 0) { @@ -638,9 +660,9 @@ static pid_t fork_a_child(int *fds, int id) } else if (pid == -1) { - ereport(FATAL, - (errmsg("failed to fork a child"), - errdetail("system call fork() failed with reason: %s", strerror(errno)))); + ereport(FATAL, + (errmsg("failed to fork a child"), + errdetail("system call fork() failed with reason: %s", strerror(errno)))); } return pid; @@ -651,7 +673,7 @@ static pid_t fork_a_child(int *fds, int id) */ static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params) { - pid_t pid; + pid_t pid; pid = fork(); @@ -659,13 +681,13 @@ static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params { on_exit_reset(); - /* Before we unconditionally closed pipe_fds[0] and pipe_fds[1] - * here, which is apparently wrong since in the start up of - * pgpool, pipe(2) is not called yet and it mistakenly closes - * fd 0. Now we check the fd > 0 before close(), expecting - * pipe returns fds greater than 0. Note that we cannot - * unconditionally remove close(2) calls since fork_a_child() - * may be called *after* pgpool starting up. + /* + * Before we unconditionally closed pipe_fds[0] and pipe_fds[1] here, + * which is apparently wrong since in the start up of pgpool, pipe(2) + * is not called yet and it mistakenly closes fd 0. Now we check the + * fd > 0 before close(), expecting pipe returns fds greater than 0. + * Note that we cannot unconditionally remove close(2) calls since + * fork_a_child() may be called *after* pgpool starting up. */ if (pipe_fds[0] > 0) { @@ -684,24 +706,25 @@ static pid_t worker_fork_a_child(ProcessType type, void (*func) (), void *params } else if (pid == -1) { - ereport(FATAL, - (errmsg("failed to fork a child"), - errdetail("system call fork() failed with reason: %s", strerror(errno)))); + ereport(FATAL, + (errmsg("failed to fork a child"), + errdetail("system call fork() failed with reason: %s", strerror(errno)))); } return pid; } -static int *create_inet_domain_sockets(const char *hostname, const int port) +static int * +create_inet_domain_sockets(const char *hostname, const int port) { - int ret; - int fd; - int one = 1; - int status; - int backlog; - int n = 0; - int *sockfds; - char *portstr; + int ret; + int fd; + int one = 1; + int status; + int backlog; + int n = 0; + int *sockfds; + char *portstr; struct addrinfo *walk; struct addrinfo *res; struct addrinfo hints; @@ -711,19 +734,22 @@ static int *create_inet_domain_sockets(const char *hostname, const int port) hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; - /* getaddrinfo() requires a string because it also accepts service names, such as "http". */ + /* + * getaddrinfo() requires a string because it also accepts service names, + * such as "http". + */ if (asprintf(&portstr, "%d", port) == -1) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("asprintf() failed: %s", strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("asprintf() failed: %s", strerror(errno)))); } if ((ret = getaddrinfo((!hostname || strcmp(hostname, "*") == 0) ? NULL : hostname, portstr, &hints, &res)) != 0) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("getaddrinfo() failed: %s", gai_strerror(ret)))); + (errmsg("failed to create INET domain socket"), + errdetail("getaddrinfo() failed: %s", gai_strerror(ret)))); } free(portstr); @@ -731,7 +757,7 @@ static int *create_inet_domain_sockets(const char *hostname, const int port) for (walk = res; walk != NULL; walk = walk->ai_next) n++; - sockfds = malloc(sizeof(int) * (n+1)); + sockfds = malloc(sizeof(int) * (n + 1)); n = 0; for (walk = res; walk != NULL; walk = walk->ai_next) sockfds[n++] = -1; @@ -742,27 +768,30 @@ static int *create_inet_domain_sockets(const char *hostname, const int port) for (walk = res; walk != NULL; walk = walk->ai_next) { - char buf[INET6_ADDRSTRLEN+1]; + char buf[INET6_ADDRSTRLEN + 1]; + memset(buf, 0, sizeof(buf)); - if ((ret = getnameinfo((struct sockaddr*)walk->ai_addr, walk->ai_addrlen, - buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) != 0) + if ((ret = getnameinfo((struct sockaddr *) walk->ai_addr, walk->ai_addrlen, + buf, sizeof(buf), NULL, 0, NI_NUMERICHOST)) != 0) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("getnameinfo() failed: \"%s\"", gai_strerror(ret)))); + (errmsg("failed to create INET domain socket"), + errdetail("getnameinfo() failed: \"%s\"", gai_strerror(ret)))); } ereport(LOG, - (errmsg("Setting up socket for %s:%d", buf, port))); + (errmsg("Setting up socket for %s:%d", buf, port))); if ((fd = socket(walk->ai_family, walk->ai_socktype, walk->ai_protocol)) == -1) { - /* A single failure is not necessarily a problem (machines without - * proper dual stack setups), but if we cannot create any socket at - * all, we report a FATAL error. */ + /* + * A single failure is not necessarily a problem (machines without + * proper dual stack setups), but if we cannot create any socket + * at all, we report a FATAL error. + */ ereport(LOG, - (errmsg("perhaps failed to create INET domain socket"), - errdetail("socket(%s) failed: \"%s\"", buf, strerror(errno)))); + (errmsg("perhaps failed to create INET domain socket"), + errdetail("socket(%s) failed: \"%s\"", buf, strerror(errno)))); continue; } @@ -770,29 +799,32 @@ static int *create_inet_domain_sockets(const char *hostname, const int port) sizeof(one))) == -1) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("socket error \"%s\"",strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("socket error \"%s\"", strerror(errno)))); } if (walk->ai_family == AF_INET6) { - /* On some machines, depending on the default value in + /* + * On some machines, depending on the default value in * /proc/sys/net/ipv6/bindv6only, sockets will listen on both IPv6 * and IPv4 at the same time. Since we are creating one socket per * address family, disable that option specifically to be sure it - * is off. */ - if ((setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one))) == -1) { + * is off. + */ + if ((setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one))) == -1) + { ereport(LOG, - (errmsg("perhaps failed to create INET domain socket"), - errdetail("setsockopt(%s, IPV6_V6ONLY) failed: \"%s\"", buf, strerror(errno)))); + (errmsg("perhaps failed to create INET domain socket"), + errdetail("setsockopt(%s, IPV6_V6ONLY) failed: \"%s\"", buf, strerror(errno)))); } } if (bind(fd, walk->ai_addr, walk->ai_addrlen) != 0) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("bind on socket failed with error \"%s\"",strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("bind on socket failed with error \"%s\"", strerror(errno)))); } backlog = pool_config->num_init_children * pool_config->listen_backlog_multiplier; @@ -803,18 +835,19 @@ static int *create_inet_domain_sockets(const char *hostname, const int port) status = listen(fd, backlog); if (status < 0) ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("listen on socket failed with error \"%s\"",strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("listen on socket failed with error \"%s\"", strerror(errno)))); sockfds[n++] = fd; } freeaddrinfo(res); - if (n == 0) { + if (n == 0) + { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("Failed to create any sockets. See the earlier LOG messages."))); + (errmsg("failed to create INET domain socket"), + errdetail("Failed to create any sockets. See the earlier LOG messages."))); } return sockfds; @@ -823,34 +856,35 @@ static int *create_inet_domain_sockets(const char *hostname, const int port) /* * create inet domain socket */ -static int create_inet_domain_socket(const char *hostname, const int port) +static int +create_inet_domain_socket(const char *hostname, const int port) { struct sockaddr_in addr; - int fd; - int status; - int one = 1; - int len; - int backlog; + int fd; + int status; + int one = 1; + int len; + int backlog; fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("socket error \"%s\"",strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("socket error \"%s\"", strerror(errno)))); } if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one))) == -1) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("socket error \"%s\"",strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("socket error \"%s\"", strerror(errno)))); } memset((char *) &addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - if (strcmp(hostname, "*")==0) + if (strcmp(hostname, "*") == 0) { addr.sin_addr.s_addr = htonl(INADDR_ANY); } @@ -862,8 +896,8 @@ static int create_inet_domain_socket(const char *hostname, const int port) if (!hostinfo) { ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("could not resolve hostname \"%s\": error \"%s\"",hostname,hstrerror(h_errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("could not resolve hostname \"%s\": error \"%s\"", hostname, hstrerror(h_errno)))); } addr.sin_addr = *(struct in_addr *) hostinfo->h_addr; @@ -872,26 +906,28 @@ static int create_inet_domain_socket(const char *hostname, const int port) addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); - status = bind(fd, (struct sockaddr *)&addr, len); + status = bind(fd, (struct sockaddr *) &addr, len); if (status == -1) { - int saved_errno = errno; - char hostname[NI_MAXHOST], servname[NI_MAXSERV]; + int saved_errno = errno; + char hostname[NI_MAXHOST], + servname[NI_MAXSERV]; + if ((status = getnameinfo((struct sockaddr *) &addr, len, hostname, sizeof(hostname), servname, sizeof(servname), 0))) { ereport(NOTICE, - (errmsg("getnameinfo failed while creating INET domain socket"), - errdetail("getnameinfo failed with reason: \"%s\"",gai_strerror(status)))); + (errmsg("getnameinfo failed while creating INET domain socket"), + errdetail("getnameinfo failed with reason: \"%s\"", gai_strerror(status)))); - snprintf(servname, sizeof(servname), "%d",port); - snprintf(hostname, sizeof(hostname), "%s",hostname); + snprintf(servname, sizeof(servname), "%d", port); + snprintf(hostname, sizeof(hostname), "%s", hostname); } ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("bind on host:\"%s\" server:\"%s\" failed with error \"%s\"",hostname, servname,strerror(saved_errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("bind on host:\"%s\" server:\"%s\" failed with error \"%s\"", hostname, servname, strerror(saved_errno)))); } - backlog = pool_config->num_init_children * pool_config->listen_backlog_multiplier; + backlog = pool_config->num_init_children * pool_config->listen_backlog_multiplier; if (backlog > PGPOOLMAXLITSENQUEUELENGTH) backlog = PGPOOLMAXLITSENQUEUELENGTH; @@ -899,8 +935,8 @@ static int create_inet_domain_socket(const char *hostname, const int port) status = listen(fd, backlog); if (status < 0) ereport(FATAL, - (errmsg("failed to create INET domain socket"), - errdetail("listen on socket failed with error \"%s\"",strerror(errno)))); + (errmsg("failed to create INET domain socket"), + errdetail("listen on socket failed with error \"%s\"", strerror(errno)))); return fd; } @@ -908,45 +944,46 @@ static int create_inet_domain_socket(const char *hostname, const int port) /* * create UNIX domain socket */ -static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp) +static int +create_unix_domain_socket(struct sockaddr_un un_addr_tmp) { struct sockaddr_un addr; - int fd; - int status; - int len; + int fd; + int status; + int len; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { - ereport(FATAL, - (errmsg("failed to create a socket"), - errdetail("Failed to create UNIX domain socket. error: \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("failed to create a socket"), + errdetail("Failed to create UNIX domain socket. error: \"%s\"", strerror(errno)))); } memset((char *) &addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", un_addr_tmp.sun_path); len = sizeof(struct sockaddr_un); - status = bind(fd, (struct sockaddr *)&addr, len); + status = bind(fd, (struct sockaddr *) &addr, len); if (status == -1) { - ereport(FATAL, - (errmsg("failed to bind a socket: \"%s\"",un_addr_tmp.sun_path), - errdetail("bind socket failed with error: \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("bind socket failed with error: \"%s\"", strerror(errno)))); } if (chmod(un_addr_tmp.sun_path, 0777) == -1) { - ereport(FATAL, - (errmsg("failed to bind a socket: \"%s\"",un_addr_tmp.sun_path), - errdetail("system call chmod failed with error: \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("system call chmod failed with error: \"%s\"", strerror(errno)))); } status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH); if (status < 0) { - ereport(FATAL, - (errmsg("failed to bind a socket: \"%s\"",un_addr_tmp.sun_path), - errdetail("system call listen() failed with error: \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("failed to bind a socket: \"%s\"", un_addr_tmp.sun_path), + errdetail("system call listen() failed with error: \"%s\"", strerror(errno)))); } return fd; } @@ -954,23 +991,25 @@ static int create_unix_domain_socket(struct sockaddr_un un_addr_tmp) /* * function called as shared memory exit call back to kill all childrens */ -static void terminate_all_childrens() +static void +terminate_all_childrens() { - pid_t wpid; - /* - * This is supposed to be called from main process - */ - if(processType != PT_MAIN) + pid_t wpid; + + /* + * This is supposed to be called from main process + */ + if (processType != PT_MAIN) return; POOL_SETMASK(&BlockSig); - kill_all_children(SIGINT); - if(pcp_pid > 0) - kill(pcp_pid, SIGINT); - pcp_pid = 0; - if(worker_pid > 0) - kill(worker_pid, SIGINT); - worker_pid = 0; + kill_all_children(SIGINT); + if (pcp_pid > 0) + kill(pcp_pid, SIGINT); + pcp_pid = 0; + if (worker_pid > 0) + kill(worker_pid, SIGINT); + worker_pid = 0; if (pool_config->use_watchdog) { if (pool_config->use_watchdog) @@ -985,17 +1024,17 @@ static void terminate_all_childrens() } } - /* wait for all children to exit */ - do - { - int ret_pid; + /* wait for all children to exit */ + do + { + int ret_pid; - wpid = waitpid(-1, &ret_pid, 0); - } while (wpid > 0 || (wpid == -1 && errno == EINTR)); + wpid = waitpid(-1, &ret_pid, 0); + } while (wpid > 0 || (wpid == -1 && errno == EINTR)); - if (wpid == -1 && errno != ECHILD) - ereport(LOG, - (errmsg("wait() failed. reason:%s", strerror(errno)))); + if (wpid == -1 && errno != ECHILD) + ereport(LOG, + (errmsg("wait() failed. reason:%s", strerror(errno)))); POOL_SETMASK(&UnBlockSig); } @@ -1004,14 +1043,15 @@ static void terminate_all_childrens() * Reuest failover. If "switch_over" is false, request all existing sessions * restarting. */ -void notice_backend_error(int node_id, unsigned char flags) +void +notice_backend_error(int node_id, unsigned char flags) { - int n = node_id; + int n = node_id; if (getpid() == mypid) { ereport(LOG, - (errmsg("notice_backend_error: called from pgpool main. ignored."))); + (errmsg("notice_backend_error: called from pgpool main. ignored."))); } else { @@ -1038,12 +1078,13 @@ void notice_backend_error(int node_id, unsigned char flags) * * wd_failover_id: The watchdog internal ID for this failover */ -bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, bool error, bool test_only) +bool +degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, bool error, bool test_only) { - int i; - int node_id[MAX_NUM_BACKENDS]; - int node_count = 0; - int elevel = LOG; + int i; + int node_id[MAX_NUM_BACKENDS]; + int node_count = 0; + int elevel = LOG; if (error) elevel = ERROR; @@ -1051,16 +1092,16 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, for (i = 0; i < count; i++) { if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS || - (!VALID_BACKEND(node_id_set[i]) && BACKEND_INFO(node_id_set[i]).quarantine == false)) + (!VALID_BACKEND(node_id_set[i]) && BACKEND_INFO(node_id_set[i]).quarantine == false)) { if (node_id_set[i] < 0 || node_id_set[i] >= MAX_NUM_BACKENDS) ereport(elevel, (errmsg("invalid degenerate backend request, node id: %d is out of range. node id must be between [0 and %d]" - ,node_id_set[i],MAX_NUM_BACKENDS))); + ,node_id_set[i], MAX_NUM_BACKENDS))); else ereport(elevel, (errmsg("invalid degenerate backend request, node id : %d status: [%d] is not valid for failover" - ,node_id_set[i],BACKEND_INFO(node_id_set[i]).backend_status))); + ,node_id_set[i], BACKEND_INFO(node_id_set[i]).backend_status))); if (test_only) return false; @@ -1070,17 +1111,18 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id_set[i]).flag)) { ereport(elevel, - (errmsg("degenerate backend request for node_id: %d from pid [%d] is canceled because failover is disallowed on the node", + (errmsg("degenerate backend request for node_id: %d from pid [%d] is canceled because failover is disallowed on the node", node_id_set[i], getpid()))); if (test_only) return false; } else { - if (!test_only) /* do not produce this log if we are in testing mode */ + if (!test_only) /* do not produce this log if we are in + * testing mode */ ereport(LOG, - (errmsg("received degenerate backend request for node_id: %d from pid [%d]", - node_id_set[i], getpid()))); + (errmsg("received degenerate backend request for node_id: %d from pid [%d]", + node_id_set[i], getpid()))); node_id[node_count++] = node_id_set[i]; } @@ -1089,14 +1131,16 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, if (node_count) { WDFailoverCMDResults res = FAILOVER_RES_PROCEED; + /* If this was only a test. Inform the caller without doing anything */ - if(test_only) + if (test_only) return true; if (!(flags & REQ_DETAIL_WATCHDOG)) { - int x; - for (x=0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) + int x; + + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) { res = wd_degenerate_backend_set(node_id_set, count, flags); if (res != FAILOVER_RES_TRANSITION) @@ -1107,12 +1151,12 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, if (res == FAILOVER_RES_TRANSITION) { /* - * What to do when cluster is still not stable - * Is proceeding to failover is the right choice ??? + * What to do when cluster is still not stable Is proceeding to + * failover is the right choice ??? */ ereport(NOTICE, (errmsg("received degenerate backend request for %d node(s) from pid [%d], But cluster is not in stable state" - , node_count, getpid()))); + ,node_count, getpid()))); } if (res == FAILOVER_RES_PROCEED) { @@ -1122,7 +1166,7 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, { ereport(LOG, (errmsg("degenerate backend request for %d node(s) from pid [%d], is changed to quarantine node request by watchdog" - , node_count, getpid()), + ,node_count, getpid()), errdetail("watchdog does not holds the quorum"))); register_node_operation_request(NODE_QUARANTINE_REQUEST, node_id, node_count, flags); @@ -1131,7 +1175,7 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, { ereport(LOG, (errmsg("degenerate backend request for %d node(s) from pid [%d], is changed to quarantine node request by watchdog" - , node_count, getpid()), + ,node_count, getpid()), errdetail("watchdog is taking time to build consensus"))); register_node_operation_request(NODE_QUARANTINE_REQUEST, node_id, node_count, flags); } @@ -1146,13 +1190,13 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, /* we will receive a sync request from master watchdog node */ ereport(LOG, (errmsg("degenerate backend request for %d node(s) from pid [%d], will be handled by watchdog" - , node_count, getpid()))); + ,node_count, getpid()))); } else { ereport(elevel, (errmsg("degenerate backend request for %d node(s) from pid [%d] is canceled by other pgpool" - , node_count, getpid()))); + ,node_count, getpid()))); return false; } } @@ -1163,16 +1207,18 @@ bool degenerate_backend_set_ex(int *node_id_set, int count, unsigned char flags, * wrapper over degenerate_backend_set_ex function to register * NODE down operation request */ -bool degenerate_backend_set(int *node_id_set, int count, unsigned char flags) +bool +degenerate_backend_set(int *node_id_set, int count, unsigned char flags) { return degenerate_backend_set_ex(node_id_set, count, flags, false, false); } /* send promote node request using SIGUSR1 */ -bool promote_backend(int node_id, unsigned char flags) +bool +promote_backend(int node_id, unsigned char flags) { WDFailoverCMDResults res = FAILOVER_RES_PROCEED; - bool ret = false; + bool ret = false; if (!SL_MODE) { @@ -1184,11 +1230,11 @@ bool promote_backend(int node_id, unsigned char flags) if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) ereport(LOG, (errmsg("invalid promote backend request, node id: %d is out of range. node id must be between [0 and %d]" - ,node_id,MAX_NUM_BACKENDS))); + ,node_id, MAX_NUM_BACKENDS))); else ereport(LOG, (errmsg("invalid promote backend request, node id : %d status: [%d] not valid" - ,node_id,BACKEND_INFO(node_id).backend_status))); + ,node_id, BACKEND_INFO(node_id).backend_status))); return false; } ereport(LOG, @@ -1198,8 +1244,9 @@ bool promote_backend(int node_id, unsigned char flags) /* If this was only a test. Inform the caller without doing anything */ if (!(flags & REQ_DETAIL_WATCHDOG)) { - int x; - for (x=0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) + int x; + + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) { res = wd_promote_backend(node_id, flags); if (res != FAILOVER_RES_TRANSITION) @@ -1210,12 +1257,12 @@ bool promote_backend(int node_id, unsigned char flags) if (res == FAILOVER_RES_TRANSITION) { /* - * What to do when cluster is still not stable - * Is proceeding to failover is the right choice ??? + * What to do when cluster is still not stable Is proceeding to + * failover is the right choice ??? */ ereport(NOTICE, (errmsg("promote backend request for node_id: %d from pid [%d], But cluster is not in stable state" - , node_id, getpid()))); + ,node_id, getpid()))); } if (res == FAILOVER_RES_PROCEED) @@ -1226,46 +1273,47 @@ bool promote_backend(int node_id, unsigned char flags) { ereport(LOG, (errmsg("promote backend request for node_id: %d from pid [%d], will be handled by watchdog" - , node_id, getpid()))); + ,node_id, getpid()))); } else if (res == FAILOVER_RES_NO_QUORUM) { ereport(LOG, (errmsg("promote backend request for node_id: %d from pid [%d], is canceled because watchdog does not hold quorum" - , node_id, getpid()))); + ,node_id, getpid()))); } else if (res == FAILOVER_RES_BUILDING_CONSENSUS) { ereport(LOG, (errmsg("promote backend request for node_id: %d from pid [%d], will be handled by watchdog, which is building consensus for request" - , node_id, getpid()))); + ,node_id, getpid()))); } else { ereport(LOG, (errmsg("promote backend request for node_id: %d from pid [%d] is canceled by other pgpool" - , node_id, getpid()))); + ,node_id, getpid()))); } return ret; } /* send failback request using SIGUSR1 */ -bool send_failback_request(int node_id,bool throw_error, unsigned char flags) +bool +send_failback_request(int node_id, bool throw_error, unsigned char flags) { WDFailoverCMDResults res = FAILOVER_RES_PROCEED; - bool ret = false; + bool ret = false; - if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || + if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || (RAW_MODE && BACKEND_INFO(node_id).backend_status != CON_DOWN && VALID_BACKEND(node_id))) { if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) - ereport(throw_error?ERROR:LOG, + ereport(throw_error ? ERROR : LOG, (errmsg("invalid failback request, node id: %d is out of range. node id must be between [0 and %d]" - ,node_id,MAX_NUM_BACKENDS))); + ,node_id, MAX_NUM_BACKENDS))); else - ereport(throw_error?ERROR:LOG, + ereport(throw_error ? ERROR : LOG, (errmsg("invalid failback request, node id : %d status: [%d] not valid for failback" - ,node_id,BACKEND_INFO(node_id).backend_status))); + ,node_id, BACKEND_INFO(node_id).backend_status))); return false; } @@ -1279,16 +1327,20 @@ bool send_failback_request(int node_id,bool throw_error, unsigned char flags) /* set the update flags */ ereport(LOG, (errmsg("failback request from pid [%d] is changed to update status request because node_id: %d was quarantined", - getpid(),node_id))); + getpid(), node_id))); flags |= REQ_DETAIL_UPDATE; } else { - /* no need to go to watchdog if it's an update or already initiated from watchdog */ + /* + * no need to go to watchdog if it's an update or already initiated + * from watchdog + */ if (!(flags & REQ_DETAIL_WATCHDOG)) { - int x; - for (x=0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) + int x; + + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) { res = wd_send_failback_request(node_id, flags); if (res != FAILOVER_RES_TRANSITION) @@ -1301,12 +1353,12 @@ bool send_failback_request(int node_id,bool throw_error, unsigned char flags) if (res == FAILOVER_RES_TRANSITION) { /* - * What to do when cluster is still not stable - * Is proceeding to failover is the right choice ??? + * What to do when cluster is still not stable Is proceeding to + * failover is the right choice ??? */ ereport(NOTICE, (errmsg("failback request for node_id: %d from pid [%d], But cluster is not in stable state" - , node_id, getpid()))); + ,node_id, getpid()))); } if (res == FAILOVER_RES_PROCEED) @@ -1317,29 +1369,30 @@ bool send_failback_request(int node_id,bool throw_error, unsigned char flags) { ereport(LOG, (errmsg("failback request for node_id: %d from pid [%d], will be handled by watchdog" - , node_id, getpid()))); + ,node_id, getpid()))); } else { - ereport(throw_error?ERROR:LOG, + ereport(throw_error ? ERROR : LOG, (errmsg("failback request for node_id: %d from pid [%d] is canceled by other pgpool" - , node_id, getpid()))); + ,node_id, getpid()))); } return ret; } static RETSIGTYPE exit_handler(int sig) { - int i; - pid_t wpid; - int *walk; + int i; + pid_t wpid; + int *walk; + + int save_errno = errno; - int save_errno = errno; POOL_SETMASK(&AuthBlockSig); /* - * this could happen in a child process if a signal has been sent - * before resetting signal handler + * this could happen in a child process if a signal has been sent before + * resetting signal handler */ if (getpid() != mypid) { @@ -1354,15 +1407,16 @@ static RETSIGTYPE exit_handler(int sig) return; } exiting = 1; - processState = EXITING; + processState = EXITING; - /* Close listen socket */ + /* Close listen socket */ for (walk = fds; *walk != -1; walk++) close(*walk); for (i = 0; i < pool_config->num_init_children; i++) { - pid_t pid = process_info[i].pid; + pid_t pid = process_info[i].pid; + if (pid) { kill(pid, sig); @@ -1378,13 +1432,13 @@ static RETSIGTYPE exit_handler(int sig) } } - if (pcp_pid > 0) - kill(pcp_pid, sig); - pcp_pid = 0; + if (pcp_pid > 0) + kill(pcp_pid, sig); + pcp_pid = 0; - if (worker_pid > 0) - kill(worker_pid, sig); - worker_pid = 0; + if (worker_pid > 0) + kill(worker_pid, sig); + worker_pid = 0; if (pool_config->use_watchdog) { @@ -1398,12 +1452,12 @@ static RETSIGTYPE exit_handler(int sig) } POOL_SETMASK(&UnBlockSig); - do - { - int ret_pid; + do + { + int ret_pid; - wpid = waitpid(-1, &ret_pid, 0); - } while (wpid > 0 || (wpid == -1 && errno == EINTR)); + wpid = waitpid(-1, &ret_pid, 0); + } while (wpid > 0 || (wpid == -1 && errno == EINTR)); process_info = NULL; exit(0); @@ -1413,17 +1467,18 @@ static RETSIGTYPE exit_handler(int sig) * Calculate next valid master node id. * If no valid node found, returns -1. */ -int get_next_master_node(void) +int +get_next_master_node(void) { - int i; + int i; - for (i=0;i<pool_config->backend_desc->num_backends;i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { /* - * Do not use VALID_BACKEND macro in raw mode. - * VALID_BACKEND return true only if the argument is master - * node id. In other words, standby nodes are false. So need - * to check backend status with VALID_BACKEND_RAW. + * Do not use VALID_BACKEND macro in raw mode. VALID_BACKEND return + * true only if the argument is master node id. In other words, + * standby nodes are false. So need to check backend status with + * VALID_BACKEND_RAW. */ if (RAW_MODE) { @@ -1449,7 +1504,7 @@ int get_next_master_node(void) */ static RETSIGTYPE sigusr1_handler(int sig) { - int save_errno = errno; + int save_errno = errno; POOL_SETMASK(&BlockSig); sigusr1_request = 1; @@ -1457,9 +1512,9 @@ static RETSIGTYPE sigusr1_handler(int sig) write(pipe_fds[1], "\0", 1); #ifdef NOT_USED - if(write(pipe_fds[1], "\0", 1) < 0) - ereport(WARNING, - (errmsg("SIGUSR1 handler: write to pipe failed with error \"%s\"", strerror(errno)))); + if (write(pipe_fds[1], "\0", 1) < 0) + ereport(WARNING, + (errmsg("SIGUSR1 handler: write to pipe failed with error \"%s\"", strerror(errno)))); #endif POOL_SETMASK(&UnBlockSig); @@ -1468,7 +1523,8 @@ static RETSIGTYPE sigusr1_handler(int sig) } -static void sigusr1_interupt_processor(void) +static void +sigusr1_interupt_processor(void) { ereport(DEBUG1, (errmsg("Pgpool-II parent process received SIGUSR1"))); @@ -1492,7 +1548,7 @@ static void sigusr1_interupt_processor(void) { ereport(LOG, (errmsg("Pgpool-II parent process received inform quarantine nodes signal from watchdog"))); - + user1SignalSlot->signalFlags[SIG_INFORM_QURANTINE_NODES] = false; degenerate_all_quarantine_nodes(); } @@ -1521,7 +1577,7 @@ static void sigusr1_interupt_processor(void) if (get_watchdog_local_node_state() == WD_STANDBY) { ereport(LOG, - (errmsg("we have joined the watchdog cluster as STANDBY node"), + (errmsg("we have joined the watchdog cluster as STANDBY node"), errdetail("syncing the backend states from the MASTER watchdog node"))); sync_backend_from_watchdog(); } @@ -1544,11 +1600,13 @@ static void sigusr1_interupt_processor(void) } /* returns true if all backends are down */ -static bool check_all_backend_down(void) +static bool +check_all_backend_down(void) { - int i; + int i; + /* Check to see if all backends are down */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (BACKEND_INFO(i).backend_status != CON_DOWN && BACKEND_INFO(i).backend_status != CON_UNUSED) @@ -1566,38 +1624,42 @@ static bool check_all_backend_down(void) * backend connection error, failover/failback request, if possible * failover() must be called under protecting signals. */ -static void failover(void) +static void +failover(void) { - int i, j, k; - int node_id; - int new_master; - int new_primary = -1; - int nodes[MAX_NUM_BACKENDS]; - bool need_to_restart_children = true; - bool partial_restart = false; - int status; - int sts; - bool need_to_restart_pcp = false; - bool all_backend_down = true; - bool sync_required = false; + int i, + j, + k; + int node_id; + int new_master; + int new_primary = -1; + int nodes[MAX_NUM_BACKENDS]; + bool need_to_restart_children = true; + bool partial_restart = false; + int status; + int sts; + bool need_to_restart_pcp = false; + bool all_backend_down = true; + bool sync_required = false; ereport(DEBUG1, - (errmsg("failover handler called"))); + (errmsg("failover handler called"))); memset(nodes, 0, sizeof(int) * MAX_NUM_BACKENDS); /* - * this could happen in a child process if a signal has been sent - * before resetting signal handler + * this could happen in a child process if a signal has been sent before + * resetting signal handler */ if (getpid() != mypid) { ereport(DEBUG1, - (errmsg("failover handler called"), + (errmsg("failover handler called"), errdetail("I am not parent"))); kill(pcp_pid, SIGUSR2); return; } + /* * processing SIGTERM, SIGINT or SIGQUIT */ @@ -1622,18 +1684,19 @@ static void failover(void) Req_info->switching = true; switching = 1; - for(;;) + for (;;) { POOL_REQUEST_KIND reqkind; - int queue_index; - int node_id_set[MAX_NUM_BACKENDS]; - int node_count; + int queue_index; + int node_id_set[MAX_NUM_BACKENDS]; + int node_count; unsigned char request_details; - bool search_primary = true; + bool search_primary = true; pool_semaphore_lock(REQUEST_INFO_SEM); - if(Req_info->request_queue_tail == Req_info->request_queue_head) /* request queue is empty*/ + if (Req_info->request_queue_tail == Req_info->request_queue_head) /* request queue is + * empty */ { switching = 0; Req_info->switching = false; @@ -1644,15 +1707,15 @@ static void failover(void) /* make a local copy of request */ Req_info->request_queue_head++; queue_index = Req_info->request_queue_head % MAX_REQUEST_QUEUE_SIZE; - memcpy(node_id_set, Req_info->request[queue_index].node_id , (sizeof(int) * Req_info->request[queue_index].count)); + memcpy(node_id_set, Req_info->request[queue_index].node_id, (sizeof(int) * Req_info->request[queue_index].count)); reqkind = Req_info->request[queue_index].kind; request_details = Req_info->request[queue_index].request_details; node_count = Req_info->request[queue_index].count; pool_semaphore_unlock(REQUEST_INFO_SEM); ereport(DEBUG1, - (errmsg("failover handler"), - errdetail("kind: %d flags: %x node_count: %d index:%d", reqkind, request_details, node_count, queue_index))); + (errmsg("failover handler"), + errdetail("kind: %d flags: %x node_count: %d index:%d", reqkind, request_details, node_count, queue_index))); if (reqkind == CLOSE_IDLE_REQUEST) { @@ -1664,11 +1727,12 @@ static void failover(void) wd_failover_start(); /* - * if not in replication mode/master slave mode, we treat this a restart request. - * otherwise we need to check if we have already failovered. + * if not in replication mode/master slave mode, we treat this a + * restart request. otherwise we need to check if we have already + * failovered. */ ereport(DEBUG1, - (errmsg("failover handler"), + (errmsg("failover handler"), errdetail("starting to select new master node"))); node_id = node_id_set[0]; @@ -1677,23 +1741,23 @@ static void failover(void) { if (node_id < 0 || node_id >= MAX_NUM_BACKENDS || (reqkind == NODE_UP_REQUEST && !(RAW_MODE && - BACKEND_INFO(node_id).backend_status == CON_DOWN) && VALID_BACKEND(node_id)) || + BACKEND_INFO(node_id).backend_status == CON_DOWN) && VALID_BACKEND(node_id)) || (reqkind == NODE_DOWN_REQUEST && !VALID_BACKEND(node_id))) { if (node_id < 0 || node_id >= MAX_NUM_BACKENDS) ereport(LOG, - (errmsg("invalid failback request, node id: %d is invalid. node id must be between [0 and %d]",node_id,MAX_NUM_BACKENDS))); + (errmsg("invalid failback request, node id: %d is invalid. node id must be between [0 and %d]", node_id, MAX_NUM_BACKENDS))); else ereport(LOG, - (errmsg("invalid failback request, status: [%d] of node id : %d is invalid for failback",BACKEND_INFO(node_id).backend_status,node_id))); + (errmsg("invalid failback request, status: [%d] of node id : %d is invalid for failback", BACKEND_INFO(node_id).backend_status, node_id))); continue; } ereport(LOG, - (errmsg("starting fail back. reconnect host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + (errmsg("starting fail back. reconnect host %s(%d)", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); /* Check to see if all backends are down */ all_backend_down = check_all_backend_down(); @@ -1705,29 +1769,38 @@ static void failover(void) { /* remove the quarantine flag */ BACKEND_INFO(node_id).quarantine = false; - /* do not search for primary node when handling the quarantine nodes */ + + /* + * do not search for primary node when handling the quarantine + * nodes + */ search_primary = false; + /* - * recalculate the master node id after setting the - * backend status of quarantined node, this will bring - * us to the old master_node_id that was beofre the quarantine state + * recalculate the master node id after setting the backend + * status of quarantined node, this will bring us to the old + * master_node_id that was beofre the quarantine state */ Req_info->master_node_id = get_next_master_node(); if (Req_info->primary_node_id == -1 && BACKEND_INFO(node_id).role == ROLE_PRIMARY) { /* - * if the failback request is for the quarantined node and that - * node had a primary role before it was quarantined, - * restore the primary node status for that node. - * this is important for the failover script to get the proper value of - * old primary + * if the failback request is for the quarantined node and + * that node had a primary role before it was quarantined, + * restore the primary node status for that node. this is + * important for the failover script to get the proper + * value of old primary */ ereport(LOG, - (errmsg("failover: failing back the quarantine node that was primary before it was quarantined"), + (errmsg("failover: failing back the quarantine node that was primary before it was quarantined"), errdetail("all children needs a restart"))); Req_info->primary_node_id = node_id; - /* since we changed the primary node so restart of all children is required */ + + /* + * since we changed the primary node so restart of all + * children is required + */ need_to_restart_children = true; partial_restart = false; } @@ -1748,13 +1821,14 @@ static void failover(void) } else { - /* The request is a proper failbak request - * and not because of the update status of quarantined node + /* + * The request is a proper failbak request and not because of + * the update status of quarantined node */ - (void)write_status_file(); + (void) write_status_file(); trigger_failover_command(node_id, pool_config->failback_command, - MASTER_NODE_ID, get_next_master_node(), PRIMARY_NODE_ID); + MASTER_NODE_ID, get_next_master_node(), PRIMARY_NODE_ID); } sync_required = true; @@ -1764,9 +1838,9 @@ static void failover(void) if (node_id != -1 && VALID_BACKEND(node_id)) { ereport(LOG, - (errmsg("starting promotion. promote host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + (errmsg("starting promotion. promote host %s(%d)", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); } else { @@ -1775,23 +1849,24 @@ static void failover(void) continue; } } - else /* NODE_DOWN_REQUEST && NODE_QUARANTINE_REQUEST*/ + else /* NODE_DOWN_REQUEST && + * NODE_QUARANTINE_REQUEST */ { - int cnt = 0; + int cnt = 0; for (i = 0; i < node_count; i++) { - if (node_id_set[i] != -1 && ( BACKEND_INFO(node_id_set[i]).quarantine ==true || - ((RAW_MODE && VALID_BACKEND_RAW(node_id_set[i])) || - VALID_BACKEND(node_id_set[i])))) + if (node_id_set[i] != -1 && (BACKEND_INFO(node_id_set[i]).quarantine == true || + ((RAW_MODE && VALID_BACKEND_RAW(node_id_set[i])) || + VALID_BACKEND(node_id_set[i])))) { ereport(LOG, (errmsg("starting %s. shutdown host %s(%d)", - (reqkind == NODE_QUARANTINE_REQUEST)?"quarantine":"degeneration", - BACKEND_INFO(node_id_set[i]).backend_hostname, - BACKEND_INFO(node_id_set[i]).backend_port))); + (reqkind == NODE_QUARANTINE_REQUEST) ? "quarantine" : "degeneration", + BACKEND_INFO(node_id_set[i]).backend_hostname, + BACKEND_INFO(node_id_set[i]).backend_port))); - BACKEND_INFO(node_id_set[i]).backend_status = CON_DOWN; /* set down status */ + BACKEND_INFO(node_id_set[i]).backend_status = CON_DOWN; /* set down status */ pool_set_backend_status_changed_time(node_id_set[i]); if (reqkind == NODE_QUARANTINE_REQUEST) { @@ -1800,10 +1875,11 @@ static void failover(void) else { /* - * if the degeneration request is for the quarantined node and that - * node had a primary role before it was quarantined, - * Restore the primary node status for that node before degenerating it. - * This is important for the failover script to get the proper valueo of + * if the degeneration request is for the quarantined + * node and that node had a primary role before it was + * quarantined, Restore the primary node status for + * that node before degenerating it. This is important + * for the failover script to get the proper valueo of * old primary */ if (Req_info->primary_node_id == -1 && @@ -1816,7 +1892,7 @@ static void failover(void) search_primary = false; } BACKEND_INFO(node_id_set[i]).quarantine = false; - (void)write_status_file(); + (void) write_status_file(); } /* save down node */ @@ -1843,22 +1919,25 @@ static void failover(void) ereport(DEBUG1, (errmsg("failover/failback request details: STREAM: %d reqkind: %d detail: %x node_id: %d", - STREAM, reqkind, request_details & REQ_DETAIL_SWITCHOVER, - node_id))); - - /* On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication - * and request is NODE_UP_REQUEST (failback case) we don't need to - * restart all children. Existing session will not use newly - * attached node, but load balanced node is not changed until this - * session ends, so it's harmless anyway. - */ + STREAM, reqkind, request_details & REQ_DETAIL_SWITCHOVER, + node_id))); + + /* + * On 2011/5/2 Tatsuo Ishii says: if mode is streaming replication and + * request is NODE_UP_REQUEST (failback case) we don't need to restart + * all children. Existing session will not use newly attached node, + * but load balanced node is not changed until this session ends, so + * it's harmless anyway. + */ + /* * On 2015/9/21 Tatsuo Ishii says: this judgment is not sufficient if * all backends were down. Child process has local status in which all * backends are down. In this case even if new connection arrives from * frontend, the child will not accept it because the local status * shows all backends are down. For this purpose we refer to - * "all_backend_down" variable, which was set before updating backend status. + * "all_backend_down" variable, which was set before updating backend + * status. * * See bug 248 for more details. */ @@ -1866,8 +1945,8 @@ static void failover(void) if (STREAM && reqkind == NODE_UP_REQUEST && all_backend_down == false) { /* - * The decision to restart/no-restart children for update status request has already been - * made + * The decision to restart/no-restart children for update status + * request has already been made */ if (!(request_details & REQ_DETAIL_UPDATE)) { @@ -1875,7 +1954,7 @@ static void failover(void) (errmsg("Do not restart children because we are failing back node id %d host: %s port: %d and we are in streaming replication mode and not all backends were down", node_id, BACKEND_INFO(node_id).backend_hostname, BACKEND_INFO(node_id).backend_port))); - + need_to_restart_children = false; partial_restart = false; } @@ -1899,11 +1978,11 @@ static void failover(void) for (i = 0; i < pool_config->num_init_children; i++) { - bool restart = false; + bool restart = false; - for (j=0;j<pool_config->max_pool;j++) + for (j = 0; j < pool_config->max_pool; j++) { - for (k=0;k<NUM_BACKENDS;k++) + for (k = 0; k < NUM_BACKENDS; k++) { ConnectionInfo *con = pool_coninfo(i, j, k); @@ -1920,7 +1999,8 @@ static void failover(void) if (restart) { - pid_t pid = process_info[i].pid; + pid_t pid = process_info[i].pid; + if (pid) { kill(pid, SIGQUIT); @@ -1939,12 +2019,13 @@ static void failover(void) /* kill all children */ for (i = 0; i < pool_config->num_init_children; i++) { - pid_t pid = process_info[i].pid; + pid_t pid = process_info[i].pid; + if (pid) { kill(pid, SIGQUIT); ereport(DEBUG1, - (errmsg("failover handler"), + (errmsg("failover handler"), errdetail("kill process with PID:%d", pid))); } } @@ -1952,8 +2033,10 @@ static void failover(void) need_to_restart_children = true; partial_restart = false; } - /* Exec failover_command if needed - * We do not execute failover when request is quarantine type + + /* + * Exec failover_command if needed We do not execute failover when + * request is quarantine type */ if (reqkind == NODE_DOWN_REQUEST) { @@ -1962,7 +2045,7 @@ static void failover(void) if (nodes[i]) { trigger_failover_command(i, pool_config->failover_command, - MASTER_NODE_ID, new_master, REAL_PRIMARY_NODE_ID); + MASTER_NODE_ID, new_master, REAL_PRIMARY_NODE_ID); sync_required = true; } } @@ -1974,14 +2057,16 @@ static void failover(void) } else if (reqkind == NODE_QUARANTINE_REQUEST) { - /* if the quarantine node was the primary node - * set the newprimary to -1 (invalid) + /* + * if the quarantine node was the primary node set the newprimary + * to -1 (invalid) */ if (Req_info->primary_node_id == node_id) { /* * set the role of the node, This will help us restore the - * primary node id when the node will come out from quarantine state + * primary node id when the node will come out from quarantine + * state */ BACKEND_INFO(node_id).role = ROLE_PRIMARY; new_primary = -1; @@ -1991,11 +2076,12 @@ static void failover(void) new_primary = Req_info->primary_node_id; } } + /* - * If the down node was a standby node in streaming replication - * mode, we can avoid calling find_primary_node_repeatedly() and - * recognize the former primary as the new primary node, which - * will reduce the time to process standby down. + * If the down node was a standby node in streaming replication mode, + * we can avoid calling find_primary_node_repeatedly() and recognize + * the former primary as the new primary node, which will reduce the + * time to process standby down. */ else if (SL_MODE && reqkind == NODE_DOWN_REQUEST) @@ -2008,7 +2094,7 @@ static void failover(void) { if (Req_info->primary_node_id >= 0) BACKEND_INFO(Req_info->primary_node_id).role = ROLE_STANDBY; - new_primary = find_primary_node_repeatedly(); + new_primary = find_primary_node_repeatedly(); } } else if (search_primary == false) @@ -2019,14 +2105,16 @@ static void failover(void) } else { - new_primary = find_primary_node_repeatedly(); + new_primary = find_primary_node_repeatedly(); } + /* - * If follow_master_command is provided and in master/slave - * streaming replication mode, we start degenerating all backends - * as they are not replicated anymore. + * If follow_master_command is provided and in master/slave streaming + * replication mode, we start degenerating all backends as they are + * not replicated anymore. */ - int follow_cnt = 0; + int follow_cnt = 0; + if (STREAM) { if (*pool_config->follow_master_command != '\0' || @@ -2042,16 +2130,18 @@ static void failover(void) for (i = 0; i < pool_config->backend_desc->num_backends; i++) { /* do not degenerate the new primary */ - if ((new_primary >= 0) && (i != new_primary)) { + if ((new_primary >= 0) && (i != new_primary)) + { BackendInfo *bkinfo; + bkinfo = pool_get_node_info(i); ereport(LOG, (errmsg("starting follow degeneration. shutdown host %s(%d)", - bkinfo->backend_hostname, - bkinfo->backend_port))); + bkinfo->backend_hostname, + bkinfo->backend_port))); bkinfo->backend_status = CON_DOWN; /* set down status */ pool_set_backend_status_changed_time(i); - (void)write_status_file(); + (void) write_status_file(); follow_cnt++; } @@ -2076,7 +2166,7 @@ static void failover(void) if ((follow_cnt > 0) && (*pool_config->follow_master_command != '\0')) { follow_pid = fork_follow_child(Req_info->master_node_id, new_primary, - Req_info->primary_node_id); + Req_info->primary_node_id); } /* Save primary node id */ @@ -2108,12 +2198,12 @@ static void failover(void) /* Kill children and restart them if needed */ if (need_to_restart_children) { - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { /* - * Try to kill pgpool child because previous kill signal - * may not be received by pgpool child. This could happen - * if multiple PostgreSQL are going down (or even starting + * Try to kill pgpool child because previous kill signal may + * not be received by pgpool child. This could happen if + * multiple PostgreSQL are going down (or even starting * pgpool, without starting PostgreSQL can trigger this). * Child calls degenerate_backend() and it tries to aquire * semaphore to write a failover request. In this case the @@ -2121,13 +2211,13 @@ static void failover(void) * received. */ - bool restart = false; + bool restart = false; if (partial_restart) { - for (j=0;j<pool_config->max_pool;j++) + for (j = 0; j < pool_config->max_pool; j++) { - for (k=0;k<NUM_BACKENDS;k++) + for (k = 0; k < NUM_BACKENDS; k++) { ConnectionInfo *con = pool_coninfo(i, j, k); @@ -2163,10 +2253,11 @@ static void failover(void) else { - /* Set restart request to each child. Children will exit(1) + /* + * Set restart request to each child. Children will exit(1) * whenever they are convenient. */ - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { process_info[i].need_to_restart = 1; } @@ -2184,11 +2275,11 @@ static void failover(void) { ereport(LOG, (errmsg("failback done. reconnect host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); /* Fork health check process if needed */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (health_check_pids[i] == 0) { @@ -2205,34 +2296,37 @@ static void failover(void) { ereport(LOG, (errmsg("promotion done. promoted host %s(%d)", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); } else { - /* Temporary black magic. Without this regression 055 does not finish */ + /* + * Temporary black magic. Without this regression 055 does not + * finish + */ fprintf(stderr, "%s done. shutdown host %s(%d)", - (reqkind == NODE_DOWN_REQUEST)?"failover":"quarantine", - BACKEND_INFO(node_id).backend_hostname, + (reqkind == NODE_DOWN_REQUEST) ? "failover" : "quarantine", + BACKEND_INFO(node_id).backend_hostname, BACKEND_INFO(node_id).backend_port); ereport(LOG, (errmsg("%s done. shutdown host %s(%d)", - (reqkind == NODE_DOWN_REQUEST)?"failover":"quarantine", - BACKEND_INFO(node_id).backend_hostname, - BACKEND_INFO(node_id).backend_port))); + (reqkind == NODE_DOWN_REQUEST) ? "failover" : "quarantine", + BACKEND_INFO(node_id).backend_hostname, + BACKEND_INFO(node_id).backend_port))); } need_to_restart_pcp = true; } switching = 0; Req_info->switching = false; - /* kick wakeup_handler in pcp_child to notice that - * failover/failback done + /* + * kick wakeup_handler in pcp_child to notice that failover/failback done */ kill(pcp_pid, SIGUSR2); - if(need_to_restart_pcp) + if (need_to_restart_pcp) { sleep(1); @@ -2276,7 +2370,8 @@ static void failover(void) */ static RETSIGTYPE health_check_timer_handler(int sig) { - int save_errno = errno; + int save_errno = errno; + POOL_SETMASK(&BlockSig); health_check_timer_expired = 1; POOL_SETMASK(&UnBlockSig); @@ -2299,10 +2394,11 @@ do_health_check(bool use_template_db, volatile int *health_check_node_id) POOL_CONNECTION_POOL_SLOT *slot; BackendInfo *bkinfo; static char *dbname; - int i; - bool all_nodes_healthy = false; - char *password = get_pgpool_config_user_password(pool_config->health_check_user, - pool_config->health_check_password); + int i; + bool all_nodes_healthy = false; + char *password = get_pgpool_config_user_password(pool_config->health_check_user, + pool_config->health_check_password); + /* Do not execute health check during recovery */ if (*InRecovery) return false; @@ -2317,28 +2413,29 @@ do_health_check(bool use_template_db, volatile int *health_check_node_id) dbname, pool_config->health_check_user))); /* - * Start checking the backed nodes starting from the - * previously failed node + * Start checking the backed nodes starting from the previously failed + * node */ - for (i=*health_check_node_id;i<pool_config->backend_desc->num_backends;i++) + for (i = *health_check_node_id; i < pool_config->backend_desc->num_backends; i++) { *health_check_node_id = i; + /* - * Make sure that health check timer has not been expired. - * Before called health_check(), health_check_timer_expired is - * set to 0. However it is possible that while processing DB - * nodes health check timer expired. + * Make sure that health check timer has not been expired. Before + * called health_check(), health_check_timer_expired is set to 0. + * However it is possible that while processing DB nodes health check + * timer expired. */ if (health_check_timer_expired) { ereport(ERROR, - (errmsg("health check timer has been already expired before attempting to connect backend node %d", i))); + (errmsg("health check timer has been already expired before attempting to connect backend node %d", i))); } bkinfo = pool_get_node_info(i); ereport(DEBUG1, - (errmsg("Backend DB node %d status is %d", i, bkinfo->backend_status))); + (errmsg("Backend DB node %d status is %d", i, bkinfo->backend_status))); if (bkinfo->backend_status == CON_UNUSED || @@ -2347,16 +2444,16 @@ do_health_check(bool use_template_db, volatile int *health_check_node_id) all_nodes_healthy = true; ereport(DEBUG1, - (errmsg("Trying to make persistent DB connection to backend node %d having status %d", i, bkinfo->backend_status))); + (errmsg("Trying to make persistent DB connection to backend node %d having status %d", i, bkinfo->backend_status))); slot = make_persistent_db_connection(i, bkinfo->backend_hostname, bkinfo->backend_port, dbname, pool_config->health_check_user, - password?password:"", false); + password ? password : "", false); ereport(DEBUG1, - (errmsg("persistent DB connection to backend node %d having status %d is successful", i, bkinfo->backend_status))); + (errmsg("persistent DB connection to backend node %d having status %d is successful", i, bkinfo->backend_status))); discard_persistent_db_connection(slot); } @@ -2371,7 +2468,7 @@ do_health_check(bool use_template_db, volatile int *health_check_node_id) */ static RETSIGTYPE reap_handler(int sig) { - int save_errno = errno; + int save_errno = errno; POOL_SETMASK(&BlockSig); sigchld_request = 1; @@ -2382,9 +2479,9 @@ static RETSIGTYPE reap_handler(int sig) } #ifdef NOT_USED - if(pipe_fds[1] && write(pipe_fds[1], "\0", 1) < 0) - ereport(WARNING, - (errmsg("reap_handler: write to pipe failed with error \"%s\"", strerror(errno)))); + if (pipe_fds[1] && write(pipe_fds[1], "\0", 1) < 0) + ereport(WARNING, + (errmsg("reap_handler: write to pipe failed with error \"%s\"", strerror(errno)))); #endif POOL_SETMASK(&UnBlockSig); @@ -2397,7 +2494,8 @@ static RETSIGTYPE reap_handler(int sig) * nothing more than a wrapper function over NOHANG mode waitpid() or wait3() * depending on the existance of waitpid in the system */ -pid_t pool_waitpid(int *status) +pid_t +pool_waitpid(int *status) { #ifdef HAVE_WAITPID return waitpid(-1, status, WNOHANG); @@ -2410,7 +2508,8 @@ pid_t pool_waitpid(int *status) * process_name_from_pid() * helper function for reaper() to report the terminating child process type name */ -static char* process_name_from_pid(pid_t pid) +static char * +process_name_from_pid(pid_t pid) { if (pid == pcp_pid) return "PCP child"; @@ -2425,6 +2524,7 @@ static char* process_name_from_pid(pid_t pid) } return "child"; } + /* * Attach zombie processes and restart child processes. * reaper() must be called protected from signals. @@ -2441,14 +2541,15 @@ static char* process_name_from_pid(pid_t pid) * Also the child exits with success status POOL_EXIT_NO_RESTART does not gets * restarted. */ -static void reaper(void) +static void +reaper(void) { - pid_t pid; - int status; - int i; + pid_t pid; + int status; + int i; ereport(DEBUG1, - (errmsg("reaper handler"))); + (errmsg("reaper handler"))); if (exiting) { @@ -2469,27 +2570,27 @@ static void reaper(void) while ((pid = pool_waitpid(&status)) > 0) { - pid_t new_pid = 0; - bool shutdown_system = false; - bool restart_child = true; - bool found = false; - char *exiting_process_name = process_name_from_pid(pid); + pid_t new_pid = 0; + bool shutdown_system = false; + bool restart_child = true; + bool found = false; + char *exiting_process_name = process_name_from_pid(pid); /* * Check if the terminating child wants pgpool main to go down with it */ - if(WIFEXITED(status)) + if (WIFEXITED(status)) { - if(WEXITSTATUS(status) == POOL_EXIT_FATAL) + if (WEXITSTATUS(status) == POOL_EXIT_FATAL) { ereport(DEBUG1, - (errmsg("%s process with pid: %d exit with FATAL ERROR. pgpool-II will be shutdown",exiting_process_name, pid))); + (errmsg("%s process with pid: %d exit with FATAL ERROR. pgpool-II will be shutdown", exiting_process_name, pid))); shutdown_system = true; } - else if(WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) + else if (WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) { ereport(DEBUG1, - (errmsg("%s process with pid: %d exit with SUCCESS. child will not be restarted",exiting_process_name, pid))); + (errmsg("%s process with pid: %d exit with SUCCESS. child will not be restarted", exiting_process_name, pid))); restart_child = false; } @@ -2497,15 +2598,17 @@ static void reaper(void) if (WIFSIGNALED(status)) { /* Child terminated by segmentation fault. Report it */ - if(WTERMSIG(status) == SIGSEGV) + if (WTERMSIG(status) == SIGSEGV) ereport(WARNING, - (errmsg("%s process with pid: %d was terminated by segmentation fault", exiting_process_name,pid))); + (errmsg("%s process with pid: %d was terminated by segmentation fault", exiting_process_name, pid))); else ereport(LOG, (errmsg("%s process with pid: %d exits with status %d by signal %d", exiting_process_name, pid, status, WTERMSIG(status)))); - /* If the watchdog process was terminated abonormally. - * we need to set the cleanup flag so that the new watchdog process - * can start without problems + + /* + * If the watchdog process was terminated abonormally. we need to + * set the cleanup flag so that the new watchdog process can start + * without problems */ if (pool_config->use_watchdog && pid == watchdog_pid) { @@ -2514,13 +2617,13 @@ static void reaper(void) } else ereport(LOG, - (errmsg("%s process with pid: %d exits with status %d", exiting_process_name,pid, status))); + (errmsg("%s process with pid: %d exits with status %d", exiting_process_name, pid, status))); /* if exiting child process was PCP handler */ if (pid == pcp_pid) { found = true; - if(restart_child) + if (restart_child) { pcp_pid = pcp_fork_a_child(pcp_unix_fd, pcp_inet_fd, pcp_conf_file); new_pid = pcp_pid; @@ -2548,7 +2651,7 @@ static void reaper(void) if (watchdog_pid == pid) { found = true; - if(restart_child) + if (restart_child) { watchdog_pid = initialize_watchdog(); new_pid = watchdog_pid; @@ -2559,7 +2662,7 @@ static void reaper(void) else if (wd_lifecheck_pid == pid) { found = true; - if(restart_child) + if (restart_child) { wd_lifecheck_pid = initialize_watchdog_lifecheck(); new_pid = wd_lifecheck_pid; @@ -2568,13 +2671,15 @@ static void reaper(void) wd_lifecheck_pid = 0; } } - /* we are not able to identify the exiting process yet. - * check if the exiting process was child process (handling PG clients) + + /* + * we are not able to identify the exiting process yet. check if the + * exiting process was child process (handling PG clients) */ if (found == false) { /* look for exiting child's pid */ - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { if (pid == process_info[i].pid) { @@ -2596,7 +2701,7 @@ static void reaper(void) /* Check health check process */ if (found == false) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (pid == health_check_pids[i]) { @@ -2612,16 +2717,16 @@ static void reaper(void) } } } - + if (shutdown_system) ereport(FATAL, - (errmsg("%s process exit with fatal error. exiting pgpool-II",exiting_process_name))); + (errmsg("%s process exit with fatal error. exiting pgpool-II", exiting_process_name))); else if (restart_child && new_pid) { /* Report if the child was restarted */ ereport(LOG, - (errmsg("fork a new %s process with pid: %d",exiting_process_name, new_pid))); + (errmsg("fork a new %s process with pid: %d", exiting_process_name, new_pid))); } else { @@ -2662,8 +2767,8 @@ pool_get_node_count(void) int * pool_get_process_list(int *array_size) { - int *array; - int i; + int *array; + int i; *array_size = pool_config->num_init_children; array = palloc0(*array_size * sizeof(int)); @@ -2679,7 +2784,7 @@ pool_get_process_list(int *array_size) ProcessInfo * pool_get_process_info(pid_t pid) { - int i; + int i; for (i = 0; i < pool_config->num_init_children; i++) if (process_info[i].pid == pid) @@ -2692,7 +2797,8 @@ pool_get_process_info(pid_t pid) * handle SIGUSR2 * Wakeup all processes */ -static void wakeup_children(void) +static void +wakeup_children(void) { kill_all_children(SIGUSR2); } @@ -2700,7 +2806,7 @@ static void wakeup_children(void) static RETSIGTYPE wakeup_handler(int sig) { - int save_errno = errno; + int save_errno = errno; wakeup_request = 1; if (processState != INITIALIZING) @@ -2708,9 +2814,9 @@ static RETSIGTYPE wakeup_handler(int sig) POOL_SETMASK(&BlockSig); write(pipe_fds[1], "\0", 1); #ifdef NOT_USED - if(write(pipe_fds[1], "\0", 1) < 0) + if (write(pipe_fds[1], "\0", 1) < 0) ereport(WARNING, - (errmsg("wakeup_handler: write to pipe failed with error \"%s\"", strerror(errno)))); + (errmsg("wakeup_handler: write to pipe failed with error \"%s\"", strerror(errno)))); #endif POOL_SETMASK(&UnBlockSig); } @@ -2723,15 +2829,15 @@ static RETSIGTYPE wakeup_handler(int sig) */ static RETSIGTYPE reload_config_handler(int sig) { - int save_errno = errno; + int save_errno = errno; POOL_SETMASK(&BlockSig); reload_config_request = 1; write(pipe_fds[1], "\0", 1); #ifdef NOT_USED - if(write(pipe_fds[1], "\0", 1) < 0) - ereport(WARNING, - (errmsg("reload_config_handler: write to pipe failed with error \"%s\"", strerror(errno)))); + if (write(pipe_fds[1], "\0", 1) < 0) + ereport(WARNING, + (errmsg("reload_config_handler: write to pipe failed with error \"%s\"", strerror(errno)))); #endif POOL_SETMASK(&UnBlockSig); @@ -2739,21 +2845,24 @@ static RETSIGTYPE reload_config_handler(int sig) errno = save_errno; } -static void kill_all_children(int sig) +static void +kill_all_children(int sig) { - int i; - if(process_info) - { - /* kill all children */ - for (i = 0; i < pool_config->num_init_children; i++) - { - pid_t pid = process_info[i].pid; - if (pid) - { - kill(pid, sig); - } - } - } + int i; + + if (process_info) + { + /* kill all children */ + for (i = 0; i < pool_config->num_init_children; i++) + { + pid_t pid = process_info[i].pid; + + if (pid) + { + kill(pid, sig); + } + } + } /* make PCP process reload as well */ if (sig == SIGHUP && pcp_pid > 0) kill(pcp_pid, sig); @@ -2768,21 +2877,22 @@ static void kill_all_children(int sig) * otherwise 0: (no signal event occurred), -1: (error) * XXX: is it OK that select(2) error is ignored here? */ -static int pool_pause(struct timeval *timeout) +static int +pool_pause(struct timeval *timeout) { - fd_set rfds; - int n; - char dummy; + fd_set rfds; + int n; + char dummy; FD_ZERO(&rfds); FD_SET(pipe_fds[0], &rfds); - n = select(pipe_fds[0]+1, &rfds, NULL, NULL, timeout); + n = select(pipe_fds[0] + 1, &rfds, NULL, NULL, timeout); if (n == 1) - { - if(read(pipe_fds[0], &dummy, 1) < 0) - ereport(WARNING, - (errmsg("pool_pause: read on pipe failed with error \"%s\"", strerror(errno)))); - } + { + if (read(pipe_fds[0], &dummy, 1) < 0) + ereport(WARNING, + (errmsg("pool_pause: read on pipe failed with error \"%s\"", strerror(errno)))); + } return n; } @@ -2794,9 +2904,11 @@ static int pool_pause(struct timeval *timeout) * macro. Note that most of these processes are done while all signals * are blocked. */ -void pool_sleep(unsigned int second) +void +pool_sleep(unsigned int second) { - struct timeval current_time, sleep_time; + struct timeval current_time, + sleep_time; gettimeofday(&current_time, NULL); sleep_time.tv_sec = second + current_time.tv_sec; @@ -2806,7 +2918,7 @@ void pool_sleep(unsigned int second) while (sleep_time.tv_sec > current_time.tv_sec) { struct timeval timeout; - int r; + int r; timeout.tv_sec = sleep_time.tv_sec - current_time.tv_sec; timeout.tv_usec = sleep_time.tv_usec - current_time.tv_usec; @@ -2830,15 +2942,17 @@ void pool_sleep(unsigned int second) * trigger_failover_command: execute specified command at failover. * command_line is null-terminated string. */ -static int trigger_failover_command(int node, const char *command_line, - int old_master, int new_master, int old_primary) +static int +trigger_failover_command(int node, const char *command_line, + int old_master, int new_master, int old_primary) { - int r = 0; - String *exec_cmd; - char port_buf[6]; - char buf[2]; + int r = 0; + String *exec_cmd; + char port_buf[6]; + char buf[2]; BackendInfo *info; BackendInfo *newmaster; + if (command_line == NULL || (strlen(command_line) == 0)) return 0; @@ -2859,28 +2973,29 @@ static int trigger_failover_command(int node, const char *command_line, { if (*(command_line + 1)) { - char val = *(command_line + 1); + char val = *(command_line + 1); + switch (val) { - case 'p': /* failed node port */ + case 'p': /* failed node port */ snprintf(port_buf, sizeof(port_buf), "%d", info->backend_port); string_append_char(exec_cmd, port_buf); break; - case 'D': /* failed node database directory */ + case 'D': /* failed node database directory */ string_append_char(exec_cmd, info->backend_data_directory); break; - case 'd': /* failed node id */ + case 'd': /* failed node id */ snprintf(port_buf, sizeof(port_buf), "%d", node); string_append_char(exec_cmd, port_buf); break; - case 'h': /* failed host name */ + case 'h': /* failed host name */ string_append_char(exec_cmd, info->backend_hostname); break; - case 'H': /* new master host name */ + case 'H': /* new master host name */ newmaster = pool_get_node_info(new_master); if (newmaster) string_append_char(exec_cmd, newmaster->backend_hostname); @@ -2889,12 +3004,12 @@ static int trigger_failover_command(int node, const char *command_line, string_append_char(exec_cmd, "\"\""); break; - case 'm': /* new master node id */ + case 'm': /* new master node id */ snprintf(port_buf, sizeof(port_buf), "%d", new_master); string_append_char(exec_cmd, port_buf); break; - case 'r': /* new master port */ + case 'r': /* new master port */ newmaster = pool_get_node_info(get_next_master_node()); if (newmaster) { @@ -2906,7 +3021,7 @@ static int trigger_failover_command(int node, const char *command_line, string_append_char(exec_cmd, "\"\""); break; - case 'R': /* new master database directory */ + case 'R': /* new master database directory */ newmaster = pool_get_node_info(get_next_master_node()); if (newmaster) string_append_char(exec_cmd, newmaster->backend_data_directory); @@ -2915,26 +3030,28 @@ static int trigger_failover_command(int node, const char *command_line, string_append_char(exec_cmd, "\"\""); break; - case 'M': /* old master node id */ + case 'M': /* old master node id */ snprintf(port_buf, sizeof(port_buf), "%d", old_master); string_append_char(exec_cmd, port_buf); break; - case 'P': /* old primary node id */ + case 'P': /* old primary node id */ snprintf(port_buf, sizeof(port_buf), "%d", old_primary); string_append_char(exec_cmd, port_buf); break; - case '%': /* escape */ + case '%': /* escape */ string_append_char(exec_cmd, "%"); break; - default: /* ignore */ + default: /* ignore */ break; } command_line++; } - } else { + } + else + { buf[0] = *command_line; string_append_char(exec_cmd, buf); } @@ -2944,7 +3061,7 @@ static int trigger_failover_command(int node, const char *command_line, if (strlen(exec_cmd->data) != 0) { ereport(LOG, - (errmsg("execute command: %s", exec_cmd->data))); + (errmsg("execute command: %s", exec_cmd->data))); r = system(exec_cmd->data); } @@ -2959,15 +3076,16 @@ static int trigger_failover_command(int node, const char *command_line, static POOL_NODE_STATUS pool_node_status[MAX_NUM_BACKENDS]; POOL_NODE_STATUS * -verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) +verify_backend_node_status(POOL_CONNECTION_POOL_SLOT * *slots) { POOL_SELECT_RESULT *res; - int num_primaries = 0; - int num_standbys = 0; - int i, j; + int num_primaries = 0; + int num_standbys = 0; + int i, + j; BackendInfo *backend_info; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { pool_node_status[i] = POOL_NODE_STATUS_UNUSED; @@ -3018,8 +3136,8 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) if (num_primaries == 1) { /* - * If there's only one primary node and there's no standby, there's no - * point to run additional testings. + * If there's only one primary node and there's no standby, + * there's no point to run additional testings. */ ereport(DEBUG1, (errmsg("verify_backend_node_status: there's no standby node"))); @@ -3028,18 +3146,18 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) else { /* - * There are multiple primaries and there's no standby - * node. There's no way to decide which one is correct. We just - * leave the youngest primary node and detach rests if allowed. + * There are multiple primaries and there's no standby node. + * There's no way to decide which one is correct. We just leave + * the youngest primary node and detach rests if allowed. */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) { ereport(DEBUG1, (errmsg("verify_backend_node_status: decided node %d is the true primary", i))); i++; - for (;i<NUM_BACKENDS;i++) + for (; i < NUM_BACKENDS; i++) { if (pool_node_status[i] == POOL_NODE_STATUS_PRIMARY) { @@ -3064,13 +3182,13 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) */ else { - bool check_connectivity = false; - int wal_receiver_status = 0; - int wal_receiver_conninfo = 1; - char host[1024]; - char port[1024]; - int primary[MAX_NUM_BACKENDS]; - int true_primary = -1; + bool check_connectivity = false; + int wal_receiver_status = 0; + int wal_receiver_conninfo = 1; + char host[1024]; + char port[1024]; + int primary[MAX_NUM_BACKENDS]; + int true_primary = -1; ereport(DEBUG1, (errmsg("verify_backend_node_status: multiple standbys: %d", num_standbys))); @@ -3087,7 +3205,7 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) * pg_stat_wal_receiver (only >= 9.6.0) if there's more than or equal * to 1 primary. */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -3108,7 +3226,7 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) ereport(DEBUG1, (errmsg("verify_backend_node_status: checking connectivity"))); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { primary[i] = 0; @@ -3120,7 +3238,7 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) ereport(DEBUG1, (errmsg("verify_backend_node_status: %d is primary", i))); - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (pool_node_status[j] == POOL_NODE_STATUS_STANDBY) { @@ -3196,7 +3314,7 @@ verify_backend_node_status(POOL_CONNECTION_POOL_SLOT **slots) * false. If none of primaries does not own all connected standbys, * we cannot judge which primary is good. */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { ereport(DEBUG1, (errmsg("verify_backend_node_status: primary %d owns %d standbys out of %d", i, primary[i], num_standbys))); @@ -3234,33 +3352,35 @@ pool_get_node_status(void) * Find the primary node (i.e. not standby node) and returns its node * id. If no primary node is found, returns -1. */ -static int find_primary_node(void) +static int +find_primary_node(void) { BackendInfo *bkinfo; POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; - int i; + int i; POOL_NODE_STATUS *status; - int primary = -1; - char *password = get_pgpool_config_user_password(pool_config->sr_check_user, - pool_config->sr_check_password); + int primary = -1; + char *password = get_pgpool_config_user_password(pool_config->sr_check_user, + pool_config->sr_check_password); /* Streaming replication mode? */ if (!SL_MODE) { - /* No point to look for primary node if not in streaming - * replication mode. + /* + * No point to look for primary node if not in streaming replication + * mode. */ ereport(DEBUG1, (errmsg("find_primary_node: not in streaming replication mode"))); return -1; } - /* + /* * First check for "ALWAYS_MASTER" flags exists. If so, do not perform * actual primary node check and just returns the node id. */ - for(i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (POOL_ALWAYS_MASTER & BACKEND_INFO(i).flag) { @@ -3273,7 +3393,7 @@ static int find_primary_node(void) /* * Establish connections to backend */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { slots[i] = NULL; @@ -3286,7 +3406,7 @@ static int find_primary_node(void) bkinfo->backend_port, pool_config->sr_check_database, pool_config->sr_check_user, - password?password:"", true); + password ? password : "", true); if (!slots[i]) { ereport(LOG, @@ -3294,19 +3414,19 @@ static int find_primary_node(void) } } - if(password) + if (password) pfree(password); /* Verify backend status */ status = verify_backend_node_status(slots); - for(i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (status[i] == POOL_NODE_STATUS_PRIMARY) { /* This is the primary */ ereport(LOG, - (errmsg("find_primary_node: primary node is %d",i))); + (errmsg("find_primary_node: primary node is %d", i))); primary = i; } else if (status[i] == POOL_NODE_STATUS_STANDBY) @@ -3322,7 +3442,7 @@ static int find_primary_node(void) } } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (slots[i]) discard_persistent_db_connection(slots[i]); @@ -3331,32 +3451,33 @@ static int find_primary_node(void) return primary; } -static int find_primary_node_repeatedly(void) +static int +find_primary_node_repeatedly(void) { - int sec; - int node_id = -1; + int sec; + int node_id = -1; /* Streaming replication mode? */ if (!SL_MODE) { - /* No point to look for primary node if not in streaming - * replication mode. + /* + * No point to look for primary node if not in streaming replication + * mode. */ ereport(DEBUG1, - (errmsg("find_primary_node: not in streaming replication mode"))); + (errmsg("find_primary_node: not in streaming replication mode"))); return -1; } /* * Try to find the new primary node and keep trying for - * search_primary_node_timeout seconds. - * search_primary_node_timeout = 0 means never timeout and keep searching - * indefinitely + * search_primary_node_timeout seconds. search_primary_node_timeout = 0 + * means never timeout and keep searching indefinitely */ ereport(LOG, - (errmsg("find_primary_node_repeatedly: waiting for finding a primary node"))); + (errmsg("find_primary_node_repeatedly: waiting for finding a primary node"))); for (sec = 0; (pool_config->search_primary_node_timeout == 0 || - sec < pool_config->search_primary_node_timeout); sec++) + sec < pool_config->search_primary_node_timeout); sec++) { node_id = find_primary_node(); if (node_id != -1) @@ -3369,10 +3490,11 @@ static int find_primary_node_repeatedly(void) /* * fork a follow child */ -pid_t fork_follow_child(int old_master, int new_primary, int old_primary) +pid_t +fork_follow_child(int old_master, int new_primary, int old_primary) { - pid_t pid; - int i; + pid_t pid; + int i; pid = fork(); @@ -3382,10 +3504,11 @@ pid_t fork_follow_child(int old_master, int new_primary, int old_primary) processType = PT_FOLLOWCHILD; ereport(LOG, - (errmsg("start triggering follow command."))); + (errmsg("start triggering follow command."))); for (i = 0; i < pool_config->backend_desc->num_backends; i++) { BackendInfo *bkinfo; + bkinfo = pool_get_node_info(i); if (bkinfo->backend_status == CON_DOWN) trigger_failover_command(i, pool_config->follow_master_command, @@ -3403,17 +3526,20 @@ pid_t fork_follow_child(int old_master, int new_primary, int old_primary) } -static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) +static void +initialize_shared_mem_objects(bool clear_memcache_oidmaps) { - int size,i; + int size, + i; + /* - * con_info is a 3 dimension array: i corresponds to pgpool child - * process, j corresponds to connection pool in each process and k - * corresponds to backends in each connection pool. + * con_info is a 3 dimension array: i corresponds to pgpool child process, + * j corresponds to connection pool in each process and k corresponds to + * backends in each connection pool. * - * XXX: Before 2010/4/12 this was a 2 dimension array: i - * corresponds to pgpool child process, j corresponds to - * connection pool in each process. Of course this was wrong. + * XXX: Before 2010/4/12 this was a 2 dimension array: i corresponds to + * pgpool child process, j corresponds to connection pool in each process. + * Of course this was wrong. */ size = pool_coninfo_size(); con_info = pool_shared_memory_create(size); @@ -3432,7 +3558,7 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) for (i = 0; i < pool_config->num_init_children; i++) { - process_info[i].connection_info = pool_coninfo(i,0,0); + process_info[i].connection_info = pool_coninfo(i, 0, 0); } user1SignalSlot = pool_shared_memory_create(sizeof(User1SignalSlot)); @@ -3442,13 +3568,13 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) ereport(DEBUG1, (errmsg("Request info are: sizeof(POOL_REQUEST_INFO) %zu bytes requested for shared memory", sizeof(POOL_REQUEST_INFO)))); + /* - * Initialize backend status area. - * From now on, VALID_BACKEND macro can be used. - * (get_next_master_node() uses VALID_BACKEND) + * Initialize backend status area. From now on, VALID_BACKEND macro can be + * used. (get_next_master_node() uses VALID_BACKEND) */ - for (i=0;i<MAX_NUM_BACKENDS;i++) + for (i = 0; i < MAX_NUM_BACKENDS; i++) { my_backend_status[i] = &(BACKEND_INFO(i).backend_status); } @@ -3473,7 +3599,7 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) { if (pool_is_shmem_cache()) { - size_t size; + size_t size; size = pool_shared_memory_cache_size(); pool_init_memory_cache(size); @@ -3481,8 +3607,8 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) size = pool_shared_memory_fsmm_size(); if (size == 0) ereport(FATAL, - (errmsg("invalid shared memory size"), - errdetail("pool_shared_memory_fsmm_size error"))); + (errmsg("invalid shared memory size"), + errdetail("pool_shared_memory_fsmm_size error"))); pool_init_fsmm(size); @@ -3491,7 +3617,7 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) pool_discard_oid_maps(); ereport(LOG, - (errmsg("pool_discard_oid_maps: discarded memqcache oid maps"))); + (errmsg("pool_discard_oid_maps: discarded memqcache oid maps"))); pool_hash_init(pool_config->memqcache_max_num_cache); } @@ -3503,12 +3629,12 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) { pool_discard_oid_maps(); ereport(LOG, - (errmsg("discarded memqcache oid maps"))); + (errmsg("discarded memqcache oid maps"))); } else { ereport(DEBUG1, - (errmsg("skipped discarding memqcache oid maps"))); + (errmsg("skipped discarding memqcache oid maps"))); } } #endif @@ -3529,33 +3655,34 @@ static void initialize_shared_mem_objects(bool clear_memcache_oidmaps) /* * Read the status file */ -static int read_status_file(bool discard_status) +static int +read_status_file(bool discard_status) { - FILE *fd; - char fnamebuf[POOLMAXPATHLEN]; - int i; - bool someone_wakeup = false; - bool is_old_format; + FILE *fd; + char fnamebuf[POOLMAXPATHLEN]; + int i; + bool someone_wakeup = false; + bool is_old_format; snprintf(fnamebuf, sizeof(fnamebuf), "%s/%s", pool_config->logdir, STATUS_FILE_NAME); fd = fopen(fnamebuf, "r"); if (!fd) { ereport(LOG, - (errmsg("Backend status file %s does not exist", fnamebuf))); + (errmsg("Backend status file %s does not exist", fnamebuf))); return -1; } /* - * If discard_status is true, unlink pgpool_status and - * do not restore previous status. + * If discard_status is true, unlink pgpool_status and do not restore + * previous status. */ if (discard_status) { fclose(fd); if (unlink(fnamebuf) == 0) ereport(LOG, - (errmsg("Backend status file %s discarded", fnamebuf))); + (errmsg("Backend status file %s discarded", fnamebuf))); else ereport(WARNING, (errmsg("failed to discard backend status file: \"%s\" with reason: \"%s\"", fnamebuf, strerror(errno)))); @@ -3570,13 +3697,13 @@ static int read_status_file(bool discard_status) if (fread(&backend_rec, 1, sizeof(backend_rec), fd) == sizeof(backend_rec)) { /* It's likely old binary format status file */ - for (i=0;i< pool_config->backend_desc->num_backends;i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { if (backend_rec.status[i] == CON_DOWN) { BACKEND_INFO(i).backend_status = CON_DOWN; pool_set_backend_status_changed_time(i); - (void)write_status_file(); + (void) write_status_file(); ereport(LOG, (errmsg("read_status_file: %d th backend is set to down status", i))); } @@ -3585,7 +3712,7 @@ static int read_status_file(bool discard_status) { BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; pool_set_backend_status_changed_time(i); - (void)write_status_file(); + (void) write_status_file(); someone_wakeup = true; } else @@ -3604,16 +3731,13 @@ static int read_status_file(bool discard_status) if (!is_old_format) { /* - * Fall back to new ascii format file. - * the format looks like(case is ignored): + * Fall back to new ascii format file. the format looks like(case is + * ignored): * - * up|down|unused - * UP|down|unused - * : - * : + * up|down|unused UP|down|unused : : */ #define MAXLINE 10 - char readbuf[MAXLINE]; + char readbuf[MAXLINE]; fd = fopen(fnamebuf, "r"); if (!fd) @@ -3623,16 +3747,16 @@ static int read_status_file(bool discard_status) return -1; } - for (i=0;i<MAX_NUM_BACKENDS;i++) + for (i = 0; i < MAX_NUM_BACKENDS; i++) { BACKEND_INFO(i).backend_status = CON_UNUSED; pool_set_backend_status_changed_time(i); } - for (i=0;;i++) + for (i = 0;; i++) { - readbuf[MAXLINE-1] = '\0'; - if (fgets(readbuf, MAXLINE-1, fd) == 0) + readbuf[MAXLINE - 1] = '\0'; + if (fgets(readbuf, MAXLINE - 1, fd) == 0) break; if (!strncasecmp("up", readbuf, 2)) @@ -3655,8 +3779,8 @@ static int read_status_file(bool discard_status) else { ereport(WARNING, - (errmsg("invalid data in status file, ignoring..."), - errdetail("backend:%d status is invalid: \"%s\"",i,readbuf))); + (errmsg("invalid data in status file, ignoring..."), + errdetail("backend:%d status is invalid: \"%s\"", i, readbuf))); } } fclose(fd); @@ -3667,12 +3791,12 @@ static int read_status_file(bool discard_status) */ if (someone_wakeup == false) { - for (i=0;i< pool_config->backend_desc->num_backends;i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { BACKEND_INFO(i).backend_status = CON_CONNECT_WAIT; pool_set_backend_status_changed_time(i); } - (void)write_status_file(); + (void) write_status_file(); } return 0; @@ -3681,33 +3805,34 @@ static int read_status_file(bool discard_status) /* * Write the status file */ -int write_status_file() +int +write_status_file() { - FILE *fd; - int fdnum; - char fnamebuf[POOLMAXPATHLEN]; - char buf[10]; - int i; + FILE *fd; + int fdnum; + char fnamebuf[POOLMAXPATHLEN]; + char buf[10]; + int i; - if (!pool_config) + if (!pool_config) { ereport(WARNING, (errmsg("pool_config is not set"))); return 0; } - /* Check to see if all nodes are down status. - * If so, skip writing status file. - * So pgpool_status will - * always reflect the last set of nodes to which any data was written. - * Upon restart, if the up-to-date (previously "up") node is in fact down - * (regardless of whether the stale ("down") node is back up), pgpool - * will detect this in its health check and will fail; if the up-to-date - * (previously "up") node is back up, then pgpool will commence using it. + /* + * Check to see if all nodes are down status. If so, skip writing status + * file. So pgpool_status will always reflect the last set of nodes to + * which any data was written. Upon restart, if the up-to-date (previously + * "up") node is in fact down (regardless of whether the stale ("down") + * node is back up), pgpool will detect this in its health check and will + * fail; if the up-to-date (previously "up") node is back up, then pgpool + * will commence using it. * * See [pgpool-general: 4721] for more discussion. */ - for (i=0;i< pool_config->backend_desc->num_backends;i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { if (BACKEND_INFO(i).backend_status != CON_DOWN) break; @@ -3726,14 +3851,14 @@ int write_status_file() if (!fd) { ereport(WARNING, - (errmsg("failed to open status file at: \"%s\"",fnamebuf), - errdetail("\"%s\"",strerror(errno)))); + (errmsg("failed to open status file at: \"%s\"", fnamebuf), + errdetail("\"%s\"", strerror(errno)))); return -1; } - for (i=0;i< pool_config->backend_desc->num_backends;i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { - char* status; + char *status; if (BACKEND_INFO(i).backend_status == CON_UP || BACKEND_INFO(i).backend_status == CON_CONNECT_WAIT) @@ -3747,8 +3872,8 @@ int write_status_file() if (fwrite(buf, 1, strlen(buf), fd) != strlen(buf)) { ereport(WARNING, - (errmsg("failed to write status file at: \"%s\"",fnamebuf), - errdetail("\"%s\"",strerror(errno)))); + (errmsg("failed to write status file at: \"%s\"", fnamebuf), + errdetail("\"%s\"", strerror(errno)))); fclose(fd); return -1; } @@ -3757,8 +3882,8 @@ int write_status_file() if (fflush(fd) != 0) { ereport(WARNING, - (errmsg("failed to write status file at: \"%s\"",fnamebuf), - errdetail("\"%s\"",strerror(errno)))); + (errmsg("failed to write status file at: \"%s\"", fnamebuf), + errdetail("\"%s\"", strerror(errno)))); fclose(fd); return -1; } @@ -3766,16 +3891,16 @@ int write_status_file() if (fdnum < 0) { ereport(WARNING, - (errmsg("failed to get file number. fsync() will not be performed: \"%s\"",fnamebuf), - errdetail("\"%s\"",strerror(errno)))); + (errmsg("failed to get file number. fsync() will not be performed: \"%s\"", fnamebuf), + errdetail("\"%s\"", strerror(errno)))); fclose(fd); return -1; } if (fsync(fdnum) != 0) { ereport(WARNING, - (errmsg("failed to fsync(): \"%s\"",fnamebuf), - errdetail("\"%s\"",strerror(errno)))); + (errmsg("failed to fsync(): \"%s\"", fnamebuf), + errdetail("\"%s\"", strerror(errno)))); fclose(fd); return -1; } @@ -3785,17 +3910,19 @@ int write_status_file() return 0; } -static void reload_config(void) +static void +reload_config(void) { ereport(LOG, - (errmsg("reload config files."))); - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + (errmsg("reload config files."))); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(conf_file, CFGCXT_RELOAD); /* Realoading config file could change backend status */ - (void)write_status_file(); + (void) write_status_file(); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); if (pool_config->enable_pool_hba) load_hba(hba_file); kill_all_children(SIGHUP); @@ -3805,42 +3932,49 @@ static void reload_config(void) } /* Call back function to unlink the file */ -static void FileUnlink(int code, Datum path) +static void +FileUnlink(int code, Datum path) { - char* filePath = (char*)path; - if (unlink(filePath) == 0) return; + char *filePath = (char *) path; + + if (unlink(filePath) == 0) + return; + /* - * We are already exiting the system just produce a log entry to report an error + * We are already exiting the system just produce a log entry to report an + * error */ ereport(LOG, - (errmsg("unlink failed for file at path \"%s\"", filePath), - errdetail("%s", strerror(errno)))); + (errmsg("unlink failed for file at path \"%s\"", filePath), + errdetail("%s", strerror(errno)))); } -static void system_will_go_down(int code, Datum arg) +static void +system_will_go_down(int code, Datum arg) { - if(mypid != getpid()) - { - /* should never happen */ - ereport(LOG,(errmsg("system_will_go_down called from invalid process"))); - return; - } - POOL_SETMASK(&AuthBlockSig); - /* Write status file */ - (void)write_status_file(); - /* - * Terminate all childrens. But we may already have killed - * all the childrens if we come to this function because of shutdown - * signal. - */ - if(processState != EXITING) - terminate_all_childrens(); - processState = EXITING; - POOL_SETMASK(&UnBlockSig); + if (mypid != getpid()) + { + /* should never happen */ + ereport(LOG, (errmsg("system_will_go_down called from invalid process"))); + return; + } + POOL_SETMASK(&AuthBlockSig); + /* Write status file */ + (void) write_status_file(); + + /* + * Terminate all childrens. But we may already have killed all the + * childrens if we come to this function because of shutdown signal. + */ + if (processState != EXITING) + terminate_all_childrens(); + processState = EXITING; + POOL_SETMASK(&UnBlockSig); } -int pool_send_to_frontend(char* data, int len, bool flush) +int +pool_send_to_frontend(char *data, int len, bool flush) { if (processType == PT_PCP_WORKER) return send_to_pcp_frontend(data, len, flush); @@ -3849,7 +3983,8 @@ int pool_send_to_frontend(char* data, int len, bool flush) return -1; } -int pool_frontend_exists(void) +int +pool_frontend_exists(void) { if (processType == PT_PCP_WORKER) return pcp_frontend_exists(); @@ -3858,10 +3993,12 @@ int pool_frontend_exists(void) return -1; } -static void degenerate_all_quarantine_nodes(void) +static void +degenerate_all_quarantine_nodes(void) { - int i; - for (i=0;i<NUM_BACKENDS;i++) + int i; + + for (i = 0; i < NUM_BACKENDS; i++) { if (BACKEND_INFO(i).quarantine && BACKEND_INFO(i).backend_status == CON_DOWN) { @@ -3872,26 +4009,27 @@ static void degenerate_all_quarantine_nodes(void) } } -static void update_backend_quarantine_status(void) +static void +update_backend_quarantine_status(void) { - /* Reset the quarantine flag from each backend and - * set it to con_wait + /* + * Reset the quarantine flag from each backend and set it to con_wait */ - int i; - WD_STATES wd_state = get_watchdog_local_node_state(); + int i; + WD_STATES wd_state = get_watchdog_local_node_state(); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (BACKEND_INFO(i).quarantine && BACKEND_INFO(i).backend_status == CON_DOWN) { /* - * Send the failback request for the node - * we also set the watchdog flag, so that the failover should only be executed - * locally because, we will eventually send the sync backend - * message to all standby nodes + * Send the failback request for the node we also set the watchdog + * flag, so that the failover should only be executed locally + * because, we will eventually send the sync backend message to + * all standby nodes */ if (wd_state == WD_COORDINATOR) - send_failback_request(i,false, REQ_DETAIL_UPDATE | REQ_DETAIL_WATCHDOG); + send_failback_request(i, false, REQ_DETAIL_UPDATE | REQ_DETAIL_WATCHDOG); } } } @@ -3906,63 +4044,67 @@ static void update_backend_quarantine_status(void) * Pgpool-II mode and type of node status change * */ -static void sync_backend_from_watchdog(void) +static void +sync_backend_from_watchdog(void) { - bool primary_changed = false; - bool node_status_was_changed_to_down = false; - bool node_status_was_changed_to_up = false; - bool need_to_restart_children = false; - bool partial_restart = false; - bool reload_maste_node_id = false; + bool primary_changed = false; + bool node_status_was_changed_to_down = false; + bool node_status_was_changed_to_up = false; + bool need_to_restart_children = false; + bool partial_restart = false; + bool reload_maste_node_id = false; - int down_node_ids[MAX_NUM_BACKENDS]; - int down_node_ids_index = 0; - int i; + int down_node_ids[MAX_NUM_BACKENDS]; + int down_node_ids_index = 0; + int i; /* - * Ask the watchdog to get all the backend states from the Master/Coordinator - * Pgpool-II node + * Ask the watchdog to get all the backend states from the + * Master/Coordinator Pgpool-II node */ - WDPGBackendStatus* backendStatus = get_pg_backend_status_from_master_wd_node(); + WDPGBackendStatus *backendStatus = get_pg_backend_status_from_master_wd_node(); + if (!backendStatus) { ereport(WARNING, - (errmsg("failed to get the backend status from the master watchdog node"), + (errmsg("failed to get the backend status from the master watchdog node"), errdetail("using the local backend node status"))); return; } if (backendStatus->node_count <= 0) { /* - * -ve node count is returned by watchdog when the node itself is a master - * and in that case we need to use the loacl backend node status + * -ve node count is returned by watchdog when the node itself is a + * master and in that case we need to use the loacl backend node + * status */ ereport(LOG, - (errmsg("I am the master watchdog node"), + (errmsg("I am the master watchdog node"), errdetail("using the local backend node status"))); pfree(backendStatus); return; } ereport(LOG, - (errmsg("master watchdog node \"%s\" returned status for %d backend nodes",backendStatus->nodeName,backendStatus->node_count))); + (errmsg("master watchdog node \"%s\" returned status for %d backend nodes", backendStatus->nodeName, backendStatus->node_count))); ereport(DEBUG1, - (errmsg("primary node on master watchdog node \"%s\" is %d",backendStatus->nodeName,backendStatus->primary_node_id))); + (errmsg("primary node on master watchdog node \"%s\" is %d", backendStatus->nodeName, backendStatus->primary_node_id))); if (Req_info->primary_node_id != backendStatus->primary_node_id) { - /* Do not produce this log message if we are starting up the Pgpool-II*/ + /* Do not produce this log message if we are starting up the Pgpool-II */ if (processState != INITIALIZING) ereport(LOG, (errmsg("primary node:%d on master watchdog node \"%s\" is different from local primary node:%d", - backendStatus->primary_node_id,backendStatus->nodeName,Req_info->primary_node_id))); + backendStatus->primary_node_id, backendStatus->nodeName, Req_info->primary_node_id))); Req_info->primary_node_id = backendStatus->primary_node_id; primary_changed = true; } - /* update the local backend status - * Also remove quarantine flags + + /* + * update the local backend status Also remove quarantine flags */ for (i = 0; i < backendStatus->node_count; i++) { @@ -3978,7 +4120,7 @@ static void sync_backend_from_watchdog(void) node_status_was_changed_to_down = true; ereport(LOG, (errmsg("backend:%d is set to down status", i), - errdetail("backend:%d is DOWN on cluster master \"%s\"",i,backendStatus->nodeName))); + errdetail("backend:%d is DOWN on cluster master \"%s\"", i, backendStatus->nodeName))); down_node_ids[down_node_ids_index++] = i; } } @@ -3996,8 +4138,8 @@ static void sync_backend_from_watchdog(void) reload_maste_node_id = true; ereport(LOG, - (errmsg("backend:%d is set to UP status", i), - errdetail("backend:%d is UP on cluster master \"%s\"",i,backendStatus->nodeName))); + (errmsg("backend:%d is set to UP status", i), + errdetail("backend:%d is UP on cluster master \"%s\"", i, backendStatus->nodeName))); } } @@ -4020,53 +4162,54 @@ static void sync_backend_from_watchdog(void) * Check if there was no change at all */ if (node_status_was_changed_to_up == false && - node_status_was_changed_to_down == false && - primary_changed == false) + node_status_was_changed_to_down == false && + primary_changed == false) { ereport(LOG, - (errmsg("backend nodes status remains same after the sync from \"%s\"",backendStatus->nodeName))); + (errmsg("backend nodes status remains same after the sync from \"%s\"", backendStatus->nodeName))); return; } if (!STREAM) { - /* If we are not in streaming replication mode - * restart all child processes + /* + * If we are not in streaming replication mode restart all child + * processes */ ereport(LOG, - (errmsg("node status was chenged after the sync from \"%s\"",backendStatus->nodeName), + (errmsg("node status was chenged after the sync from \"%s\"", backendStatus->nodeName), errdetail("all children needs to be restarted as we are not in streaming replication mode"))); need_to_restart_children = true; partial_restart = false; } else if (primary_changed) { - /* if Primary node was changed, We should restart all - * children + /* + * if Primary node was changed, We should restart all children */ need_to_restart_children = true; partial_restart = false; ereport(LOG, - (errmsg("primary node was chenged after the sync from \"%s\"",backendStatus->nodeName), - errdetail("all children needs to be restarted"))); + (errmsg("primary node was chenged after the sync from \"%s\"", backendStatus->nodeName), + errdetail("all children needs to be restarted"))); } else { if (node_status_was_changed_to_down == false) { - /* no node was detached, So no need to restart - * any child process + /* + * no node was detached, So no need to restart any child process */ need_to_restart_children = false; partial_restart = false; ereport(LOG, - (errmsg("No backend node was detached because of backend status sync from \"%s\"",backendStatus->nodeName), + (errmsg("No backend node was detached because of backend status sync from \"%s\"", backendStatus->nodeName), errdetail("no need to restart children"))); } else { ereport(LOG, - (errmsg("%d backend node(s) were detached because of backend status sync from \"%s\"",down_node_ids_index,backendStatus->nodeName), + (errmsg("%d backend node(s) were detached because of backend status sync from \"%s\"", down_node_ids_index, backendStatus->nodeName), errdetail("restarting the children processes"))); need_to_restart_children = true; @@ -4077,22 +4220,26 @@ static void sync_backend_from_watchdog(void) /* Kill children and restart them if needed */ if (need_to_restart_children) { - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { - bool restart = false; + bool restart = false; if (partial_restart) { - int j, k; - for (j=0;j<pool_config->max_pool;j++) + int j, + k; + + for (j = 0; j < pool_config->max_pool; j++) { - for (k=0;k<NUM_BACKENDS;k++) + for (k = 0; k < NUM_BACKENDS; k++) { - int idx; + int idx; ConnectionInfo *con = pool_coninfo(i, j, k); - for (idx = 0; idx < down_node_ids_index; idx ++) + + for (idx = 0; idx < down_node_ids_index; idx++) { - int node_id = down_node_ids[idx]; + int node_id = down_node_ids[idx]; + if (con->connected && con->load_balancing_node == node_id) { ereport(LOG, @@ -4129,10 +4276,11 @@ static void sync_backend_from_watchdog(void) else { - /* Set restart request to each child. Children will exit(1) - * whenever they are convenient. + /* + * Set restart request to each child. Children will exit(1) whenever + * they are convenient. */ - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { process_info[i].need_to_restart = 1; } @@ -4149,11 +4297,11 @@ static void sync_backend_from_watchdog(void) * version number is in the static memory area. */ static int -get_server_version(POOL_CONNECTION_POOL_SLOT **slots, int node_id) +get_server_version(POOL_CONNECTION_POOL_SLOT * *slots, int node_id) { - static int server_versions[MAX_NUM_BACKENDS]; + static int server_versions[MAX_NUM_BACKENDS]; - char *query; + char *query; POOL_SELECT_RESULT *res; if (server_versions[node_id] == 0) @@ -4175,9 +4323,10 @@ get_server_version(POOL_CONNECTION_POOL_SLOT **slots, int node_id) /* * Get info from conninfo string. */ -static void get_info_from_conninfo(char *conninfo, char *host, char *port) +static void +get_info_from_conninfo(char *conninfo, char *host, char *port) { - char *p; + char *p; *host = '\0'; *port = '\0'; @@ -4209,7 +4358,8 @@ static void get_info_from_conninfo(char *conninfo, char *host, char *port) void pool_set_backend_status_changed_time(int backend_id) { - time_t tval; + time_t tval; + tval = time(NULL); BACKEND_INFO(backend_id).status_changed_time = tval; } diff --git a/src/main/pool_globals.c b/src/main/pool_globals.c index bcf06a6ee..517701bd3 100644 --- a/src/main/pool_globals.c +++ b/src/main/pool_globals.c @@ -22,6 +22,6 @@ */ #include "pool.h" -pid_t mypid; /* pgpool parent process id */ +pid_t mypid; /* pgpool parent process id */ ProcessType processType; ProcessState processState; diff --git a/src/parser/copyfuncs.c b/src/parser/copyfuncs.c index b2596fd56..f3a6a7042 100644 --- a/src/parser/copyfuncs.c +++ b/src/parser/copyfuncs.c @@ -2256,7 +2256,7 @@ _copyAppendRelInfo(const AppendRelInfo *from) * _copyPartitionedChildRelInfo */ static PartitionedChildRelInfo * -_copyPartitionedChildRelInfo(const PartitionedChildRelInfo *from) +_copyPartitionedChildRelInfo(const PartitionedChildRelInfo * from) { PartitionedChildRelInfo *newnode = makeNode(PartitionedChildRelInfo); @@ -4991,6 +4991,7 @@ copyObjectImpl(const void *from) break; #ifdef NOT_USED_IN_PGPOOL + /* * RELATION NODES */ @@ -5017,6 +5018,7 @@ copyObjectImpl(const void *from) break; #endif + /* * VALUE NODES */ @@ -5045,6 +5047,7 @@ copyObjectImpl(const void *from) break; #ifdef NOT_USED_IN_PGPOOL + /* * EXTENSIBLE NODES */ @@ -5547,6 +5550,7 @@ copyObjectImpl(const void *from) break; #ifdef NOT_USED_IN_PGPOOL + /* * MISCELLANEOUS NODES */ diff --git a/src/parser/keywords.c b/src/parser/keywords.c index 8c148d330..59e6b2a86 100644 --- a/src/parser/keywords.c +++ b/src/parser/keywords.c @@ -19,7 +19,7 @@ #include "parsenodes.h" #ifndef FRONTEND -#include "gramparse.h" /* required before parser/parse.h! */ +#include "gramparse.h" /* required before parser/parse.h! */ #define PG_KEYWORD(a,b,c) {a,b,c}, diff --git a/src/parser/list.c b/src/parser/list.c index ac546f9ba..c13d9cc34 100644 --- a/src/parser/list.c +++ b/src/parser/list.c @@ -458,7 +458,7 @@ list_member(const List *list, const void *datum) return false; } -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ /* * Return true iff 'datum' is a member of the list. Equality is * determined by using simple pointer comparison. @@ -589,7 +589,7 @@ list_delete(List *list, void *datum) return list; } -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ /* As above, but use simple pointer equality */ List * @@ -719,7 +719,7 @@ list_union(const List *list1, const List *list2) check_list_invariants(result); return result; } -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ /* * This variant of list_union() determines duplicates via simple @@ -884,7 +884,7 @@ list_difference(const List *list1, const List *list2) check_list_invariants(result); return result; } -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ /* * This variant of list_difference() determines list membership via @@ -979,7 +979,7 @@ list_append_unique(List *list, void *datum) return lappend(list, datum); } -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ /* * This variant of list_append_unique() determines list membership via @@ -1046,7 +1046,7 @@ list_concat_unique(List *list1, List *list2) check_list_invariants(list1); return list1; } -#endif /*NOT_USED_IN_PGPOOL*/ +#endif /* NOT_USED_IN_PGPOOL */ /* * This variant of list_concat_unique() determines list membership via diff --git a/src/parser/outfuncs.c b/src/parser/outfuncs.c index 2630086cd..7e22703ab 100644 --- a/src/parser/outfuncs.c +++ b/src/parser/outfuncs.c @@ -36,163 +36,163 @@ #define booltostr(x) ((x) ? "true" : "false") -void _outNode(String *str, void *obj); - -static void _outList(String *str, List *node); -static void _outIdList(String *str, List *node); -static void _outAlias(String *str, Alias *node); -static void _outRangeVar(String *str, RangeVar *node); -static void _outVar(String *str, Var *node); -static void _outConst(String *str, Const *node); -static void _outParam(String *str, Param *node); -static void _outAggref(String *str, Aggref *node); -static void _outGroupingFunc(String *str, GroupingFunc *node); -static void _outArrayRef(String *str, ArrayRef *node); -static void _outFuncExpr(String *str, FuncExpr *node); -static void _outNamedArgExpr(String *str, NamedArgExpr *node); -static void _outOpExpr(String *str, OpExpr *node); -static void _outDistinctExpr(String *str, DistinctExpr *node); -static void _outScalarArrayOpExpr(String *str, ScalarArrayOpExpr *node); -static void _outBoolExpr(String *str, BoolExpr *node); -static void _outSubLink(String *str, SubLink *node); -static void _outSubPlan(String *str, SubPlan *node); -static void _outFieldSelect(String *str, FieldSelect *node); -static void _outFieldStore(String *str, FieldStore *node); -static void _outRelabelType(String *str, RelabelType *node); -static void _outConvertRowtypeExpr(String *str, ConvertRowtypeExpr *node); -static void _outCaseExpr(String *str, CaseExpr *node); -static void _outCaseWhen(String *str, CaseWhen *node); -static void _outCaseTestExpr(String *str, CaseTestExpr *node); -static void _outArrayExpr(String *str, ArrayExpr *node); -static void _outRowExpr(String *str, RowExpr *node); -static void _outCoalesceExpr(String *str, CoalesceExpr *node); -static void _outMinMaxExpr(String *str, MinMaxExpr *node); -static void _outNullIfExpr(String *str, NullIfExpr *node); -static void _outNullTest(String *str, NullTest *node); -static void _outBooleanTest(String *str, BooleanTest *node); -static void _outCoerceToDomain(String *str, CoerceToDomain *node); -static void _outCoerceToDomainValue(String *str, CoerceToDomainValue *node); -static void _outSetToDefault(String *str, SetToDefault *node); -static void _outCurrentOfExpr(String *str, CurrentOfExpr *node); -static void _outInferenceElem(String *str, InferenceElem *node); -static void _outTargetEntry(String *str, TargetEntry *node); -static void _outRangeTblRef(String *str, RangeTblRef *node); -static void _outJoinExpr(String *str, JoinExpr *node); -static void _outFromExpr(String *str, FromExpr *node); -static void _outCreateStmt(String *str, CreateStmt *node); -static void _outCreateTableAsStmt(String *str, CreateTableAsStmt *node); -static void _outCreateForeignTableStmt(String *str, CreateForeignTableStmt *node); -static void _outImportForeignSchemaStmt(String *str, ImportForeignSchemaStmt *node); -static void _outIndexStmt(String *str, IndexStmt *node); -static void _outNotifyStmt(String *str, NotifyStmt *node); -static void _outDeclareCursorStmt(String *str, DeclareCursorStmt *node); -static void _outSelectStmt(String *str, SelectStmt *node); -static void _outFuncCall(String *str, FuncCall *node); -static void _outDefElem(String *str, DefElem *node); -static void _outLockingClause(String *str, LockingClause *node); -static void _outColumnDef(String *str, ColumnDef *node); -static void _outTypeName(String *str, TypeName *node); -static void _outTypeCast(String *str, TypeCast *node); -static void _outIndexElem(String *str, IndexElem *node); -static void _outGroupingSet(String *str, GroupingSet *node); -static void _outWithClause(String *str, WithClause *node); -static void _outCommonTableExpr(String *str, CommonTableExpr *node); -static void _outSetOperationStmt(String *str, SetOperationStmt *node); -static void _outTableSampleClause(String *str, TableSampleClause *node); -static void _outAExpr(String *str, A_Expr *node); -static void _outValue(String *str, Value *value); -static void _outColumnRef(String *str, ColumnRef *node); -static void _outParamRef(String *str, ParamRef *node); -static void _outAConst(String *str, A_Const *node); -static void _outA_Indices(String *str, A_Indices *node); -static void _outA_Indirection(String *str, A_Indirection *node); -static void _outResTarget(String *str, ResTarget *node); -static void _outMultiAssignRef(String *str, MultiAssignRef *node); -static void _outA_ArrayExpr(String *str, A_ArrayExpr *node); -static void _outWindowDef(String *str, WindowDef *node); -static void _outConstraint(String *str, Constraint *node); - -static void _outSortBy(String *str, SortBy *node); -static void _outInsertStmt(String *str, InsertStmt *node); -static void _outSetClause(String *str, List *node); -static void _outUpdateStmt(String *str, UpdateStmt *node); -static void _outDeleteStmt(String *str, DeleteStmt *node); -static void _outTransactionStmt(String *str, TransactionStmt *node); -static void _outTruncateStmt(String *str, TruncateStmt *node); -static void _outVacuumStmt(String *str, VacuumStmt *node); -static void _outExplainStmt(String *str, ExplainStmt *node); -static void _outClusterStmt(String *str, ClusterStmt *node); -static void _outCheckPointStmt(String *str, CheckPointStmt *node); -static void _outClosePortalStmt(String *str, ClosePortalStmt *node); -static void _outListenStmt(String *str, ListenStmt *node); -static void _outUnlistenStmt(String *str, UnlistenStmt *node); -static void _outLoadStmt(String *str, LoadStmt *node); -static void _outCopyStmt(String *str, CopyStmt *node); -static void _outDeallocateStmt(String *str, DeallocateStmt *node); -static void _outRenameStmt(String *str, RenameStmt *node); -static void _outCreateRoleStmt(String *str, CreateRoleStmt *node); -static void _outAlterRoleStmt(String *str, AlterRoleStmt *node); -static void _outDropRoleStmt(String *str, DropRoleStmt *node); -static void _outCreateSchemaStmt(String *str, CreateSchemaStmt *node); -static void _outVariableSetStmt(String *str, VariableSetStmt *node); -static void _outVariableShowStmt(String *str, VariableShowStmt *node); -static void _outConstraintsSetStmt(String *str, ConstraintsSetStmt *node); -static void _outAlterTableStmt(String *str, AlterTableStmt *node); -static void _outCreateSeqStmt(String *str, CreateSeqStmt *node); -static void _outAlterSeqStmt(String *str, AlterSeqStmt *node); -static void _outCreatePLangStmt(String *str, CreatePLangStmt *node); -static void _outCreateTableSpaceStmt(String *str, CreateTableSpaceStmt *node); -static void _outDropTableSpaceStmt(String *str, DropTableSpaceStmt *node); -static void _outCreateTrigStmt(String *str, CreateTrigStmt *node); -static void _outDefineStmt(String *str, DefineStmt *node); -static void _outCreateOpClassStmt(String *str, CreateOpClassStmt *node); -static void _outDropStmt(String *str, DropStmt *node); -static void _outFetchStmt(String *str, FetchStmt *node); -static void _outGrantStmt(String *str, GrantStmt *node); -static void _outGrantRoleStmt(String *str, GrantRoleStmt *node); -static void _outCreateFunctionStmt(String *str, CreateFunctionStmt *node); -static void _outAlterFunctionStmt(String *str, AlterFunctionStmt *node); -static void _outCreateCastStmt(String *str, CreateCastStmt *node); -static void _outReindexStmt(String *str, ReindexStmt *node); -static void _outRuleStmt(String *str, RuleStmt *node); -static void _outViewStmt(String *str, ViewStmt *node); -static void _outCreatedbStmt(String *str, CreatedbStmt *node); -static void _outAlterDatabaseStmt(String *str, AlterDatabaseStmt *node); -static void _outAlterDatabaseSetStmt(String *str, AlterDatabaseSetStmt *node); -static void _outDropdbStmt(String *str, DropdbStmt *node); -static void _outCreateDomainStmt(String *str, CreateDomainStmt *node); -static void _outAlterDomainStmt(String *str, AlterDomainStmt *node); -static void _outCreateConversionStmt(String *str, CreateConversionStmt *node); -static void _outPrepareStmt(String *str, PrepareStmt *node); -static void _outExecuteStmt(String *str, ExecuteStmt *node); -static void _outLockStmt(String *str, LockStmt *node); -static void _outCommentStmt(String *str, CommentStmt *node); -static void _outDiscardStmt(String *str, DiscardStmt *node); -static void _outCreateOpFamilyStmt(String *str, CreateOpFamilyStmt *node); -static void _outAlterOpFamilyStmt(String *str, AlterOpFamilyStmt *node); -static void _outCreateEnumStmt(String *str, CreateEnumStmt *node); -static void _outDropOwnedStmt(String *str, DropOwnedStmt *node); -static void _outReassignOwnedStmt(String *str, ReassignOwnedStmt *node); -static void _outAlterTSDictionaryStmt(String *str, AlterTSDictionaryStmt *node); -static void _outAlterTSConfigurationStmt(String *str, AlterTSConfigurationStmt *node); -static void _outXmlExpr(String *str, XmlExpr *node); -static void _outXmlSerialize(String *str, XmlSerialize *node); - -static void _outFuncName(String *str, List *func_name); -static void _outSetRest(String *str, VariableSetStmt *node); -static void _outSetTransactionModeList(String *str, List *list); -static void _outAlterTableCmd(String *str, AlterTableCmd *node); -static void _outOptSeqList(String *str, List *options); -static void _outObjectWithArgs(String *str, ObjectWithArgs *node); -static void _outFunctionParameter(String *str, FunctionParameter *node); -static void _outPrivilegeList(String *str, List *list); -static void _outFuncOptList(String *str, List *list); -static void _outCreatedbOptList(String *str, List *options); -static void _outOperatorArgTypes(String *str, List *args); -static void _outRangeFunction(String *str, RangeFunction *node); -static void _outRangeTableSample(String *str, RangeTableSample *node); -static void _outWithDefinition(String *str, List *def_list); -static void _outOnConflictClause(String *str, OnConflictClause *node); +void _outNode(String * str, void *obj); + +static void _outList(String * str, List *node); +static void _outIdList(String * str, List *node); +static void _outAlias(String * str, Alias *node); +static void _outRangeVar(String * str, RangeVar *node); +static void _outVar(String * str, Var *node); +static void _outConst(String * str, Const *node); +static void _outParam(String * str, Param *node); +static void _outAggref(String * str, Aggref *node); +static void _outGroupingFunc(String * str, GroupingFunc *node); +static void _outArrayRef(String * str, ArrayRef *node); +static void _outFuncExpr(String * str, FuncExpr *node); +static void _outNamedArgExpr(String * str, NamedArgExpr *node); +static void _outOpExpr(String * str, OpExpr *node); +static void _outDistinctExpr(String * str, DistinctExpr *node); +static void _outScalarArrayOpExpr(String * str, ScalarArrayOpExpr *node); +static void _outBoolExpr(String * str, BoolExpr *node); +static void _outSubLink(String * str, SubLink *node); +static void _outSubPlan(String * str, SubPlan *node); +static void _outFieldSelect(String * str, FieldSelect *node); +static void _outFieldStore(String * str, FieldStore *node); +static void _outRelabelType(String * str, RelabelType *node); +static void _outConvertRowtypeExpr(String * str, ConvertRowtypeExpr *node); +static void _outCaseExpr(String * str, CaseExpr *node); +static void _outCaseWhen(String * str, CaseWhen *node); +static void _outCaseTestExpr(String * str, CaseTestExpr *node); +static void _outArrayExpr(String * str, ArrayExpr *node); +static void _outRowExpr(String * str, RowExpr *node); +static void _outCoalesceExpr(String * str, CoalesceExpr *node); +static void _outMinMaxExpr(String * str, MinMaxExpr *node); +static void _outNullIfExpr(String * str, NullIfExpr *node); +static void _outNullTest(String * str, NullTest *node); +static void _outBooleanTest(String * str, BooleanTest *node); +static void _outCoerceToDomain(String * str, CoerceToDomain *node); +static void _outCoerceToDomainValue(String * str, CoerceToDomainValue *node); +static void _outSetToDefault(String * str, SetToDefault *node); +static void _outCurrentOfExpr(String * str, CurrentOfExpr *node); +static void _outInferenceElem(String * str, InferenceElem *node); +static void _outTargetEntry(String * str, TargetEntry *node); +static void _outRangeTblRef(String * str, RangeTblRef *node); +static void _outJoinExpr(String * str, JoinExpr *node); +static void _outFromExpr(String * str, FromExpr *node); +static void _outCreateStmt(String * str, CreateStmt *node); +static void _outCreateTableAsStmt(String * str, CreateTableAsStmt *node); +static void _outCreateForeignTableStmt(String * str, CreateForeignTableStmt *node); +static void _outImportForeignSchemaStmt(String * str, ImportForeignSchemaStmt *node); +static void _outIndexStmt(String * str, IndexStmt *node); +static void _outNotifyStmt(String * str, NotifyStmt *node); +static void _outDeclareCursorStmt(String * str, DeclareCursorStmt *node); +static void _outSelectStmt(String * str, SelectStmt *node); +static void _outFuncCall(String * str, FuncCall *node); +static void _outDefElem(String * str, DefElem *node); +static void _outLockingClause(String * str, LockingClause *node); +static void _outColumnDef(String * str, ColumnDef *node); +static void _outTypeName(String * str, TypeName *node); +static void _outTypeCast(String * str, TypeCast *node); +static void _outIndexElem(String * str, IndexElem *node); +static void _outGroupingSet(String * str, GroupingSet *node); +static void _outWithClause(String * str, WithClause *node); +static void _outCommonTableExpr(String * str, CommonTableExpr *node); +static void _outSetOperationStmt(String * str, SetOperationStmt *node); +static void _outTableSampleClause(String * str, TableSampleClause *node); +static void _outAExpr(String * str, A_Expr *node); +static void _outValue(String * str, Value *value); +static void _outColumnRef(String * str, ColumnRef *node); +static void _outParamRef(String * str, ParamRef *node); +static void _outAConst(String * str, A_Const *node); +static void _outA_Indices(String * str, A_Indices *node); +static void _outA_Indirection(String * str, A_Indirection *node); +static void _outResTarget(String * str, ResTarget *node); +static void _outMultiAssignRef(String * str, MultiAssignRef *node); +static void _outA_ArrayExpr(String * str, A_ArrayExpr *node); +static void _outWindowDef(String * str, WindowDef *node); +static void _outConstraint(String * str, Constraint *node); + +static void _outSortBy(String * str, SortBy *node); +static void _outInsertStmt(String * str, InsertStmt *node); +static void _outSetClause(String * str, List *node); +static void _outUpdateStmt(String * str, UpdateStmt *node); +static void _outDeleteStmt(String * str, DeleteStmt *node); +static void _outTransactionStmt(String * str, TransactionStmt *node); +static void _outTruncateStmt(String * str, TruncateStmt *node); +static void _outVacuumStmt(String * str, VacuumStmt *node); +static void _outExplainStmt(String * str, ExplainStmt *node); +static void _outClusterStmt(String * str, ClusterStmt *node); +static void _outCheckPointStmt(String * str, CheckPointStmt *node); +static void _outClosePortalStmt(String * str, ClosePortalStmt *node); +static void _outListenStmt(String * str, ListenStmt *node); +static void _outUnlistenStmt(String * str, UnlistenStmt *node); +static void _outLoadStmt(String * str, LoadStmt *node); +static void _outCopyStmt(String * str, CopyStmt *node); +static void _outDeallocateStmt(String * str, DeallocateStmt *node); +static void _outRenameStmt(String * str, RenameStmt *node); +static void _outCreateRoleStmt(String * str, CreateRoleStmt *node); +static void _outAlterRoleStmt(String * str, AlterRoleStmt *node); +static void _outDropRoleStmt(String * str, DropRoleStmt *node); +static void _outCreateSchemaStmt(String * str, CreateSchemaStmt *node); +static void _outVariableSetStmt(String * str, VariableSetStmt *node); +static void _outVariableShowStmt(String * str, VariableShowStmt *node); +static void _outConstraintsSetStmt(String * str, ConstraintsSetStmt *node); +static void _outAlterTableStmt(String * str, AlterTableStmt *node); +static void _outCreateSeqStmt(String * str, CreateSeqStmt *node); +static void _outAlterSeqStmt(String * str, AlterSeqStmt *node); +static void _outCreatePLangStmt(String * str, CreatePLangStmt *node); +static void _outCreateTableSpaceStmt(String * str, CreateTableSpaceStmt *node); +static void _outDropTableSpaceStmt(String * str, DropTableSpaceStmt *node); +static void _outCreateTrigStmt(String * str, CreateTrigStmt *node); +static void _outDefineStmt(String * str, DefineStmt *node); +static void _outCreateOpClassStmt(String * str, CreateOpClassStmt *node); +static void _outDropStmt(String * str, DropStmt *node); +static void _outFetchStmt(String * str, FetchStmt *node); +static void _outGrantStmt(String * str, GrantStmt *node); +static void _outGrantRoleStmt(String * str, GrantRoleStmt *node); +static void _outCreateFunctionStmt(String * str, CreateFunctionStmt *node); +static void _outAlterFunctionStmt(String * str, AlterFunctionStmt *node); +static void _outCreateCastStmt(String * str, CreateCastStmt *node); +static void _outReindexStmt(String * str, ReindexStmt *node); +static void _outRuleStmt(String * str, RuleStmt *node); +static void _outViewStmt(String * str, ViewStmt *node); +static void _outCreatedbStmt(String * str, CreatedbStmt *node); +static void _outAlterDatabaseStmt(String * str, AlterDatabaseStmt *node); +static void _outAlterDatabaseSetStmt(String * str, AlterDatabaseSetStmt *node); +static void _outDropdbStmt(String * str, DropdbStmt *node); +static void _outCreateDomainStmt(String * str, CreateDomainStmt *node); +static void _outAlterDomainStmt(String * str, AlterDomainStmt *node); +static void _outCreateConversionStmt(String * str, CreateConversionStmt *node); +static void _outPrepareStmt(String * str, PrepareStmt *node); +static void _outExecuteStmt(String * str, ExecuteStmt *node); +static void _outLockStmt(String * str, LockStmt *node); +static void _outCommentStmt(String * str, CommentStmt *node); +static void _outDiscardStmt(String * str, DiscardStmt *node); +static void _outCreateOpFamilyStmt(String * str, CreateOpFamilyStmt *node); +static void _outAlterOpFamilyStmt(String * str, AlterOpFamilyStmt *node); +static void _outCreateEnumStmt(String * str, CreateEnumStmt *node); +static void _outDropOwnedStmt(String * str, DropOwnedStmt *node); +static void _outReassignOwnedStmt(String * str, ReassignOwnedStmt *node); +static void _outAlterTSDictionaryStmt(String * str, AlterTSDictionaryStmt *node); +static void _outAlterTSConfigurationStmt(String * str, AlterTSConfigurationStmt *node); +static void _outXmlExpr(String * str, XmlExpr *node); +static void _outXmlSerialize(String * str, XmlSerialize *node); + +static void _outFuncName(String * str, List *func_name); +static void _outSetRest(String * str, VariableSetStmt *node); +static void _outSetTransactionModeList(String * str, List *list); +static void _outAlterTableCmd(String * str, AlterTableCmd *node); +static void _outOptSeqList(String * str, List *options); +static void _outObjectWithArgs(String * str, ObjectWithArgs *node); +static void _outFunctionParameter(String * str, FunctionParameter *node); +static void _outPrivilegeList(String * str, List *list); +static void _outFuncOptList(String * str, List *list); +static void _outCreatedbOptList(String * str, List *options); +static void _outOperatorArgTypes(String * str, List *args); +static void _outRangeFunction(String * str, RangeFunction *node); +static void _outRangeTableSample(String * str, RangeTableSample *node); +static void _outWithDefinition(String * str, List *def_list); +static void _outOnConflictClause(String * str, OnConflictClause *node); /* @@ -209,35 +209,38 @@ static void _outOnConflictClause(String *str, OnConflictClause *node); char * NameListToString(List *names) { - StringInfoData string; - ListCell *l; + StringInfoData string; + ListCell *l; - initStringInfo(&string); + initStringInfo(&string); - foreach(l, names) - { - Node *name = (Node *) lfirst(l); + foreach(l, names) + { + Node *name = (Node *) lfirst(l); - if (l != list_head(names)) - appendStringInfoChar(&string, '.'); + if (l != list_head(names)) + appendStringInfoChar(&string, '.'); - if (IsA(name, String)) - appendStringInfoString(&string, strVal(name)); - else if (IsA(name, A_Star)) - appendStringInfoString(&string, "*"); - else - elog(ERROR, "unexpected node type in name list: %d", - (int) nodeTag(name)); - } + if (IsA(name, String)) + appendStringInfoString(&string, strVal(name)); + else if (IsA(name, A_Star)) + appendStringInfoString(&string, "*"); + else + elog(ERROR, "unexpected node type in name list: %d", + (int) nodeTag(name)); + } - return string.data; + return string.data; } -static char *escape_string(char *str) +static char * +escape_string(char *str) { - int len = strlen(str), i, j; - char *es = palloc0(len * 2 + 1); + int len = strlen(str), + i, + j; + char *es = palloc0(len * 2 + 1); if (es == NULL) { @@ -260,14 +263,15 @@ static char *escape_string(char *str) return es; } -static void _outIdList(String *str, List *node) +static void +_outIdList(String * str, List *node) { ListCell *lc; - char first = 0; + char first = 0; foreach(lc, node) { - Value *v = lfirst(lc); + Value *v = lfirst(lc); if (first == 0) first = 1; @@ -280,10 +284,11 @@ static void _outIdList(String *str, List *node) } } -static void _outListWith(String *str, List *node, char *op) +static void +_outListWith(String * str, List *node, char *op) { ListCell *lc; - char first = 0; + char first = 0; foreach(lc, node) { @@ -298,7 +303,8 @@ static void _outListWith(String *str, List *node, char *op) } } -static void _outList(String *str, List *node) +static void +_outList(String * str, List *node) { _outListWith(str, node, ","); } @@ -321,7 +327,7 @@ outToken(StringInfo str, const char *s) #endif static void -_outAlias(String *str, Alias *node) +_outAlias(String * str, Alias *node) { string_append_char(str, " AS \""); string_append_char(str, node->aliasname); @@ -336,7 +342,7 @@ _outAlias(String *str, Alias *node) } static void -_outRangeVar(String *str, RangeVar *node) +_outRangeVar(String * str, RangeVar *node) { if (node->catalogname) { @@ -361,31 +367,31 @@ _outRangeVar(String *str, RangeVar *node) } static void -_outVar(String *str, Var *node) +_outVar(String * str, Var *node) { } static void -_outConst(String *str, Const *node) +_outConst(String * str, Const *node) { } static void -_outParam(String *str, Param *node) +_outParam(String * str, Param *node) { } static void -_outAggref(String *str, Aggref *node) +_outAggref(String * str, Aggref *node) { } static void -_outGroupingFunc(String *str, GroupingFunc *node) +_outGroupingFunc(String * str, GroupingFunc *node) { string_append_char(str, "GROUPING ("); _outNode(str, node->args); @@ -394,18 +400,18 @@ _outGroupingFunc(String *str, GroupingFunc *node) } static void -_outArrayRef(String *str, ArrayRef *node) +_outArrayRef(String * str, ArrayRef *node) { } static void -_outFuncExpr(String *str, FuncExpr *node) +_outFuncExpr(String * str, FuncExpr *node) { } static void -_outNamedArgExpr(String *str, NamedArgExpr *node) +_outNamedArgExpr(String * str, NamedArgExpr *node) { string_append_char(str, node->name); string_append_char(str, " := "); @@ -413,25 +419,25 @@ _outNamedArgExpr(String *str, NamedArgExpr *node) } static void -_outOpExpr(String *str, OpExpr *node) +_outOpExpr(String * str, OpExpr *node) { } static void -_outDistinctExpr(String *str, DistinctExpr *node) +_outDistinctExpr(String * str, DistinctExpr *node) { } static void -_outScalarArrayOpExpr(String *str, ScalarArrayOpExpr *node) +_outScalarArrayOpExpr(String * str, ScalarArrayOpExpr *node) { } static void -_outBoolExpr(String *str, BoolExpr *node) +_outBoolExpr(String * str, BoolExpr *node) { switch (node->boolop) { @@ -456,13 +462,14 @@ _outBoolExpr(String *str, BoolExpr *node) } static void -_outSubLink(String *str, SubLink *node) +_outSubLink(String * str, SubLink *node) { _outNode(str, node->testexpr); if (node->operName != NIL) { - Value *v = linitial(node->operName); + Value *v = linitial(node->operName); + if (strcmp(v->val.str, "=") == 0) string_append_char(str, " IN "); else @@ -484,7 +491,8 @@ _outSubLink(String *str, SubLink *node) case ANY_SUBLINK: if (node->operName != NIL) { - Value *v = linitial(node->operName); + Value *v = linitial(node->operName); + if (strcmp(v->val.str, "=") != 0) { string_append_char(str, v->val.str); @@ -511,45 +519,45 @@ _outSubLink(String *str, SubLink *node) } static void -_outSubPlan(String *str, SubPlan *node) +_outSubPlan(String * str, SubPlan *node) { } static void -_outFieldSelect(String *str, FieldSelect *node) +_outFieldSelect(String * str, FieldSelect *node) { } static void -_outFieldStore(String *str, FieldStore *node) +_outFieldStore(String * str, FieldStore *node) { } static void -_outRelabelType(String *str, RelabelType *node) +_outRelabelType(String * str, RelabelType *node) { } static void -_outConvertRowtypeExpr(String *str, ConvertRowtypeExpr *node) +_outConvertRowtypeExpr(String * str, ConvertRowtypeExpr *node) { } static void -_outCaseExpr(String *str, CaseExpr *node) +_outCaseExpr(String * str, CaseExpr *node) { - ListCell *lc; + ListCell *lc; string_append_char(str, "CASE "); if (node->arg) _outNode(str, node->arg); - foreach (lc, node->args) + foreach(lc, node->args) { _outNode(str, lfirst(lc)); } @@ -564,7 +572,7 @@ _outCaseExpr(String *str, CaseExpr *node) } static void -_outCaseWhen(String *str, CaseWhen *node) +_outCaseWhen(String * str, CaseWhen *node) { string_append_char(str, " WHEN "); _outNode(str, node->expr); @@ -573,13 +581,13 @@ _outCaseWhen(String *str, CaseWhen *node) } static void -_outCaseTestExpr(String *str, CaseTestExpr *node) +_outCaseTestExpr(String * str, CaseTestExpr *node) { } static void -_outArrayExpr(String *str, ArrayExpr *node) +_outArrayExpr(String * str, ArrayExpr *node) { string_append_char(str, "["); _outNode(str, node->elements); @@ -587,7 +595,7 @@ _outArrayExpr(String *str, ArrayExpr *node) } static void -_outRowExpr(String *str, RowExpr *node) +_outRowExpr(String * str, RowExpr *node) { if (node->row_format == COERCE_EXPLICIT_CAST) string_append_char(str, "ROW ("); @@ -601,7 +609,7 @@ _outRowExpr(String *str, RowExpr *node) } static void -_outCoalesceExpr(String *str, CoalesceExpr *node) +_outCoalesceExpr(String * str, CoalesceExpr *node) { string_append_char(str, "COALESCE ("); _outNode(str, node->args); @@ -609,7 +617,7 @@ _outCoalesceExpr(String *str, CoalesceExpr *node) } static void -_outMinMaxExpr(String *str, MinMaxExpr *node) +_outMinMaxExpr(String * str, MinMaxExpr *node) { if (node->op == IS_GREATEST) { @@ -626,13 +634,13 @@ _outMinMaxExpr(String *str, MinMaxExpr *node) } static void -_outNullIfExpr(String *str, NullIfExpr *node) +_outNullIfExpr(String * str, NullIfExpr *node) { } static void -_outNullTest(String *str, NullTest *node) +_outNullTest(String * str, NullTest *node) { _outNode(str, node->arg); if (node->nulltesttype == IS_NOT_NULL) @@ -642,7 +650,7 @@ _outNullTest(String *str, NullTest *node) } static void -_outBooleanTest(String *str, BooleanTest *node) +_outBooleanTest(String * str, BooleanTest *node) { _outNode(str, node->arg); @@ -675,30 +683,31 @@ _outBooleanTest(String *str, BooleanTest *node) } static void -_outCoerceToDomain(String *str, CoerceToDomain *node) +_outCoerceToDomain(String * str, CoerceToDomain *node) { } static void -_outCoerceToDomainValue(String *str, CoerceToDomainValue *node) +_outCoerceToDomainValue(String * str, CoerceToDomainValue *node) { } static void -_outSetToDefault(String *str, SetToDefault *node) +_outSetToDefault(String * str, SetToDefault *node) { string_append_char(str, "DEFAULT"); } static void -_outCurrentOfExpr(String *str, CurrentOfExpr *node) +_outCurrentOfExpr(String * str, CurrentOfExpr *node) { string_append_char(str, "CURRENT OF "); if (node->cursor_name == NULL) { - char n[10]; + char n[10]; + snprintf(n, sizeof(n), "$%d", node->cursor_param); string_append_char(str, n); } @@ -707,25 +716,25 @@ _outCurrentOfExpr(String *str, CurrentOfExpr *node) } static void -_outInferenceElem(String *str, InferenceElem *node) +_outInferenceElem(String * str, InferenceElem *node) { } static void -_outTargetEntry(String *str, TargetEntry *node) +_outTargetEntry(String * str, TargetEntry *node) { } static void -_outRangeTblRef(String *str, RangeTblRef *node) +_outRangeTblRef(String * str, RangeTblRef *node) { } static void -_outJoinExpr(String *str, JoinExpr *node) +_outJoinExpr(String * str, JoinExpr *node) { _outNode(str, node->larg); @@ -752,14 +761,14 @@ _outJoinExpr(String *str, JoinExpr *node) if (node->usingClause != NIL && IsA(node->usingClause, List)) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; string_append_char(str, " USING("); - foreach (lc, node->usingClause) + foreach(lc, node->usingClause) { - Value *value; + Value *value; if (comma == 0) comma = 1; @@ -783,13 +792,13 @@ _outJoinExpr(String *str, JoinExpr *node) } static void -_outFromExpr(String *str, FromExpr *node) +_outFromExpr(String * str, FromExpr *node) { } static void -_outOnConflictExpr(String *str, const OnConflictExpr *node) +_outOnConflictExpr(String * str, const OnConflictExpr *node) { } @@ -824,7 +833,7 @@ _outExtensibleNode(StringInfo str, const ExtensibleNode *node) *****************************************************************************/ static void -_outCreateStmt(String *str, CreateStmt *node) +_outCreateStmt(String * str, CreateStmt *node) { string_append_char(str, "CREATE "); if (node->relation->relpersistence == RELPERSISTENCE_TEMP) @@ -872,7 +881,7 @@ _outCreateStmt(String *str, CreateStmt *node) } static void -_outCreateTableAsStmt(String *str, CreateTableAsStmt *node) +_outCreateTableAsStmt(String * str, CreateTableAsStmt *node) { string_append_char(str, "CREATE "); if (node->into->rel->relpersistence == RELPERSISTENCE_TEMP) @@ -918,24 +927,24 @@ _outCreateTableAsStmt(String *str, CreateTableAsStmt *node) if (node->query) { string_append_char(str, " AS"); - _outSelectStmt(str, (SelectStmt *)node->query); + _outSelectStmt(str, (SelectStmt *) node->query); } } static void -_outCreateForeignTableStmt(String *str, CreateForeignTableStmt *node) +_outCreateForeignTableStmt(String * str, CreateForeignTableStmt *node) { } static void -_outImportForeignSchemaStmt(String *str, ImportForeignSchemaStmt *node) +_outImportForeignSchemaStmt(String * str, ImportForeignSchemaStmt *node) { } static void -_outIndexStmt(String *str, IndexStmt *node) +_outIndexStmt(String * str, IndexStmt *node) { string_append_char(str, "CREATE "); @@ -980,12 +989,12 @@ _outIndexStmt(String *str, IndexStmt *node) } static void -_outCreateStatsStmt(String *str, CreateStatsStmt *node) +_outCreateStatsStmt(String * str, CreateStatsStmt *node) { } static void -_outNotifyStmt(String *str, NotifyStmt *node) +_outNotifyStmt(String * str, NotifyStmt *node) { string_append_char(str, "NOTIFY "); string_append_char(str, "\""); @@ -994,7 +1003,7 @@ _outNotifyStmt(String *str, NotifyStmt *node) } static void -_outDeclareCursorStmt(String *str, DeclareCursorStmt *node) +_outDeclareCursorStmt(String * str, DeclareCursorStmt *node) { string_append_char(str, "DECLARE \""); string_append_char(str, node->portalname); @@ -1015,9 +1024,9 @@ _outDeclareCursorStmt(String *str, DeclareCursorStmt *node) } static void -_outSelectStmt(String *str, SelectStmt *node) +_outSelectStmt(String * str, SelectStmt *node) { - if (node->larg) /* SETOP */ + if (node->larg) /* SETOP */ { string_append_char(str, "("); _outNode(str, node->larg); @@ -1052,11 +1061,11 @@ _outSelectStmt(String *str, SelectStmt *node) } else if (node->valuesLists) /* VALUES ... */ { - ListCell *lc; - int comma = 0; + ListCell *lc; + int comma = 0; string_append_char(str, " VALUES"); - foreach (lc, node->valuesLists) + foreach(lc, node->valuesLists) { if (comma == 0) comma = 1; @@ -1072,8 +1081,8 @@ _outSelectStmt(String *str, SelectStmt *node) { if (node->intoClause) { - IntoClause *into = (IntoClause *)node->intoClause; - RangeVar *rel = (RangeVar *)into->rel; + IntoClause *into = (IntoClause *) node->intoClause; + RangeVar *rel = (RangeVar *) into->rel; string_append_char(str, "CREATE "); if (rel->relpersistence == RELPERSISTENCE_TEMP) @@ -1177,7 +1186,7 @@ _outSelectStmt(String *str, SelectStmt *node) { string_append_char(str, " LIMIT "); if (IsA(node->limitCount, A_Const) && - ((A_Const *)node->limitCount)->val.type == T_Null) + ((A_Const *) node->limitCount)->val.type == T_Null) { string_append_char(str, "ALL "); } @@ -1191,18 +1200,19 @@ _outSelectStmt(String *str, SelectStmt *node) } static void -_outFuncCall(String *str, FuncCall *node) +_outFuncCall(String * str, FuncCall *node) { - char *funcname; + char *funcname; + _outFuncName(str, node->funcname); funcname = strVal(lfirst(list_head(node->funcname))); - if(strcmp(funcname,"user") == 0 || - strcmp(funcname,"current_user") == 0 || - strcmp(funcname,"session_user") == 0 || - strcmp(funcname,"current_role") == 0) - return ; + if (strcmp(funcname, "user") == 0 || + strcmp(funcname, "current_user") == 0 || + strcmp(funcname, "session_user") == 0 || + strcmp(funcname, "current_role") == 0) + return; string_append_char(str, "("); @@ -1240,18 +1250,18 @@ _outFuncCall(String *str, FuncCall *node) } static void -_outDefElem(String *str, DefElem *node) +_outDefElem(String * str, DefElem *node) { } static void -_outLockingClause(String *str, LockingClause *node) +_outLockingClause(String * str, LockingClause *node) { if (node == NULL) return; - switch(node->strength) + switch (node->strength) { case LCS_FORKEYSHARE: string_append_char(str, " FOR KEY SHARE"); @@ -1289,12 +1299,12 @@ _outLockingClause(String *str, LockingClause *node) } static void -_outTriggerTransition(String *str, TriggerTransition *node) +_outTriggerTransition(String * str, TriggerTransition *node) { } static void -_outColumnDef(String *str, ColumnDef *node) +_outColumnDef(String * str, ColumnDef *node) { string_append_char(str, "\""); string_append_char(str, node->colname); @@ -1304,32 +1314,31 @@ _outColumnDef(String *str, ColumnDef *node) } static void -_outTypeName(String *str, TypeName *node) +_outTypeName(String * str, TypeName *node) { - /* don't quote SystemType name, because - * 1. char is not "char". - * 2. in 8.4, interval with fields cause error. - * =# SELECT '1'::"interval" year; - * ERROR: syntax error at or near "year" - * LINE 1: SELECT '1'::"interval" year; + /* + * don't quote SystemType name, because 1. char is not "char". 2. in 8.4, + * interval with fields cause error. =# SELECT '1'::"interval" year; + * ERROR: syntax error at or near "year" LINE 1: SELECT '1'::"interval" + * year; */ if (list_length(node->names) == 2 && strcmp("pg_catalog", strVal(linitial(node->names))) == 0) - { + { string_append_char(str, strVal(lsecond(node->names))); if (strcmp("interval", strVal(lsecond(node->names))) == 0) { if (node->typmods != NIL) { - A_Const *v = (A_Const *) linitial(node->typmods); + A_Const *v = (A_Const *) linitial(node->typmods); int mask = v->val.val.ival; - /* precision for SECOND field. - * backword comaptibility. - * use `'1.2 second'::interval(0) second' - * not `'1.2 second'::interval second(0)'(standarad for 8.4). + /* + * precision for SECOND field. backword comaptibility. use + * `'1.2 second'::interval(0) second' not `'1.2 + * second'::interval second(0)'(standarad for 8.4). */ if ((INTERVAL_MASK(SECOND) & mask) && list_length(node->typmods) == 2) @@ -1376,24 +1385,25 @@ _outTypeName(String *str, TypeName *node) } else { - ListCell *lc; - char dot = 0; + ListCell *lc; + char dot = 0; - foreach (lc, node->names) + foreach(lc, node->names) { - Value *v = (Value *) lfirst(lc); - char *typename = v->val.str; + Value *v = (Value *) lfirst(lc); + char *typename = v->val.str; if (dot == 0) dot = 1; else string_append_char(str, "."); - if(node->typemod < 0) + if (node->typemod < 0) { string_append_char(str, "\""); string_append_char(str, typename); string_append_char(str, "\""); - } else + } + else string_append_char(str, typename); } } @@ -1408,9 +1418,9 @@ _outTypeName(String *str, TypeName *node) if (node->arrayBounds != NIL) { - ListCell *lc; + ListCell *lc; - foreach (lc, node->arrayBounds) + foreach(lc, node->arrayBounds) { if (intVal(lfirst(lc)) == -1) string_append_char(str, "[]"); @@ -1425,7 +1435,7 @@ _outTypeName(String *str, TypeName *node) } static void -_outTypeCast(String *str, TypeCast *node) +_outTypeCast(String * str, TypeCast *node) { _outNode(str, node->arg); string_append_char(str, "::"); @@ -1434,18 +1444,18 @@ _outTypeCast(String *str, TypeCast *node) } static void -_outCollateClause(String *str, const CollateClause *node) +_outCollateClause(String * str, const CollateClause *node) { if (node->arg) _outNode(str, node->arg); string_append_char(str, " COLLATE "); string_append_char(str, "\""); - string_append_char(str, ((Value *)linitial(node->collname))->val.str); + string_append_char(str, ((Value *) linitial(node->collname))->val.str); string_append_char(str, "\""); } static void -_outIndexElem(String *str, IndexElem *node) +_outIndexElem(String * str, IndexElem *node) { if (node->name) { @@ -1466,7 +1476,7 @@ _outIndexElem(String *str, IndexElem *node) } static void -_outGroupingSet(String *str, GroupingSet *node) +_outGroupingSet(String * str, GroupingSet *node) { switch (node->kind) { @@ -1494,7 +1504,7 @@ _outGroupingSet(String *str, GroupingSet *node) } static void -_outWithClause(String *str, WithClause *node) +_outWithClause(String * str, WithClause *node) { string_append_char(str, " WITH "); if (node->recursive) @@ -1504,7 +1514,7 @@ _outWithClause(String *str, WithClause *node) } static void -_outCommonTableExpr(String *str, CommonTableExpr *node) +_outCommonTableExpr(String * str, CommonTableExpr *node) { string_append_char(str, "\""); string_append_char(str, node->ctename); @@ -1523,29 +1533,29 @@ _outCommonTableExpr(String *str, CommonTableExpr *node) } static void -_outSetOperationStmt(String *str, SetOperationStmt *node) +_outSetOperationStmt(String * str, SetOperationStmt *node) { } static void -_outTableSampleClause(String *str, TableSampleClause *node) +_outTableSampleClause(String * str, TableSampleClause *node) { } static void -_outAExpr(String *str, A_Expr *node) +_outAExpr(String * str, A_Expr *node) { - Value *v; + Value *v; switch (node->kind) { case AEXPR_OP: if (list_length(node->name) == 1) { - Value *op = (Value *) lfirst(list_head(node->name)); + Value *op = (Value *) lfirst(list_head(node->name)); string_append_char(str, " ("); _outNode(str, node->lexpr); @@ -1610,7 +1620,7 @@ _outAExpr(String *str, A_Expr *node) case AEXPR_IN: _outNode(str, node->lexpr); - v = (Value *)lfirst(list_head(node->name)); + v = (Value *) lfirst(list_head(node->name)); if (v->val.str[0] == '=') string_append_char(str, " IN ("); else @@ -1621,14 +1631,15 @@ _outAExpr(String *str, A_Expr *node) case AEXPR_LIKE: _outNode(str, node->lexpr); - v = (Value *)lfirst(list_head(node->name)); + v = (Value *) lfirst(list_head(node->name)); if (!strcmp(v->val.str, "~~")) string_append_char(str, " LIKE "); else string_append_char(str, " NOT LIKE "); if (IsA(node->rexpr, FuncCall)) { - FuncCall *rexpr = (FuncCall*)node->rexpr; + FuncCall *rexpr = (FuncCall *) node->rexpr; + _outNode(str, linitial(rexpr->args)); string_append_char(str, " ESCAPE "); _outNode(str, lsecond(rexpr->args)); @@ -1639,14 +1650,15 @@ _outAExpr(String *str, A_Expr *node) case AEXPR_ILIKE: _outNode(str, node->lexpr); - v = (Value *)lfirst(list_head(node->name)); + v = (Value *) lfirst(list_head(node->name)); if (!strcmp(v->val.str, "~~*")) string_append_char(str, " ILIKE "); else string_append_char(str, " NOT ILIKE "); if (IsA(node->rexpr, FuncCall)) { - FuncCall *rexpr = (FuncCall*)node->rexpr; + FuncCall *rexpr = (FuncCall *) node->rexpr; + _outNode(str, linitial(rexpr->args)); string_append_char(str, " ESCAPE "); _outNode(str, lsecond(rexpr->args)); @@ -1657,14 +1669,15 @@ _outAExpr(String *str, A_Expr *node) case AEXPR_SIMILAR: _outNode(str, node->lexpr); - v = (Value *)lfirst(list_head(node->name)); + v = (Value *) lfirst(list_head(node->name)); if (!strcmp(v->val.str, "~")) string_append_char(str, " SIMILAR TO "); else string_append_char(str, " NOT SIMILAR TO "); if (IsA(node->rexpr, FuncCall)) { - FuncCall *rexpr = (FuncCall*)node->rexpr; + FuncCall *rexpr = (FuncCall *) node->rexpr; + _outNode(str, linitial(rexpr->args)); string_append_char(str, " ESCAPE "); _outNode(str, lsecond(rexpr->args)); @@ -1676,33 +1689,33 @@ _outAExpr(String *str, A_Expr *node) case AEXPR_BETWEEN: _outNode(str, node->lexpr); string_append_char(str, " BETWEEN "); - _outNode(str, linitial((List *)node->rexpr)); + _outNode(str, linitial((List *) node->rexpr)); string_append_char(str, " AND "); - _outNode(str, lsecond((List *)node->rexpr)); + _outNode(str, lsecond((List *) node->rexpr)); break; case AEXPR_NOT_BETWEEN: _outNode(str, node->lexpr); string_append_char(str, " NOT BETWEEN "); - _outNode(str, linitial((List *)node->rexpr)); + _outNode(str, linitial((List *) node->rexpr)); string_append_char(str, " AND "); - _outNode(str, lsecond((List *)node->rexpr)); + _outNode(str, lsecond((List *) node->rexpr)); break; case AEXPR_BETWEEN_SYM: _outNode(str, node->lexpr); string_append_char(str, " BETWEEN SYMMETRIC "); - _outNode(str, linitial((List *)node->rexpr)); + _outNode(str, linitial((List *) node->rexpr)); string_append_char(str, " AND "); - _outNode(str, lsecond((List *)node->rexpr)); + _outNode(str, lsecond((List *) node->rexpr)); break; case AEXPR_NOT_BETWEEN_SYM: _outNode(str, node->lexpr); string_append_char(str, " NOT BETWEEN SYMMETRIC "); - _outNode(str, linitial((List *)node->rexpr)); + _outNode(str, linitial((List *) node->rexpr)); string_append_char(str, " AND "); - _outNode(str, lsecond((List *)node->rexpr)); + _outNode(str, lsecond((List *) node->rexpr)); break; case AEXPR_PAREN: @@ -1717,9 +1730,9 @@ _outAExpr(String *str, A_Expr *node) } static void -_outValue(String *str, Value *value) +_outValue(String * str, Value *value) { - char buf[16]; + char buf[16]; switch (value->type) { @@ -1748,18 +1761,18 @@ _outValue(String *str, Value *value) } static void -_outColumnRef(String *str, ColumnRef *node) +_outColumnRef(String * str, ColumnRef *node) { - ListCell *c; - char first = 0; + ListCell *c; + char first = 0; - foreach (c, node->fields) + foreach(c, node->fields) { - Node *n = (Node *) lfirst(c); + Node *n = (Node *) lfirst(c); if (IsA(n, String)) { - Value *v = (Value *) lfirst(c); + Value *v = (Value *) lfirst(c); if (first == 0) first = 1; @@ -1783,9 +1796,9 @@ _outColumnRef(String *str, ColumnRef *node) } static void -_outParamRef(String *str, ParamRef *node) +_outParamRef(String * str, ParamRef *node) { - char buf[16]; + char buf[16]; snprintf(buf, 16, "%d", node->number); string_append_char(str, "$"); @@ -1793,9 +1806,9 @@ _outParamRef(String *str, ParamRef *node) } static void -_outAConst(String *str, A_Const *node) +_outAConst(String * str, A_Const *node) { - char buf[16]; + char buf[16]; switch (node->val.type) { @@ -1824,7 +1837,7 @@ _outAConst(String *str, A_Const *node) } static void -_outA_Indices(String *str, A_Indices *node) +_outA_Indices(String * str, A_Indices *node) { string_append_char(str, "["); if (node->lidx) @@ -1837,9 +1850,9 @@ _outA_Indices(String *str, A_Indices *node) } static void -_outA_Indirection(String *str, A_Indirection *node) +_outA_Indirection(String * str, A_Indirection *node) { - ListCell *lc; + ListCell *lc; if (node->indirection != NIL) { @@ -1854,9 +1867,9 @@ _outA_Indirection(String *str, A_Indirection *node) string_append_char(str, ")"); } - foreach (lc, node->indirection) + foreach(lc, node->indirection) { - Node *ind = lfirst(lc); + Node *ind = lfirst(lc); if (IsA(ind, A_Star)) /* foo.* */ @@ -1869,22 +1882,22 @@ _outA_Indirection(String *str, A_Indirection *node) string_append_char(str, "\""); } else - /* foo[1] (A_Indices)*/ + /* foo[1] (A_Indices) */ _outNode(str, ind); } } } static void -_outA_ArrayExpr(String *str, A_ArrayExpr *node) +_outA_ArrayExpr(String * str, A_ArrayExpr *node) { string_append_char(str, "ARRAY ["); _outNode(str, node->elements); - string_append_char(str,"]"); + string_append_char(str, "]"); } static void -_outResTarget(String *str, ResTarget *node) +_outResTarget(String * str, ResTarget *node) { if (node->indirection != NIL) { @@ -1909,13 +1922,13 @@ _outResTarget(String *str, ResTarget *node) static void -_outMultiAssignRef(String *str, MultiAssignRef *node) +_outMultiAssignRef(String * str, MultiAssignRef *node) { _outNode(str, node->source); } static void -_outWindowDef(String *str, WindowDef *node) +_outWindowDef(String * str, WindowDef *node) { if (node->name) { @@ -2000,7 +2013,7 @@ _outWindowDef(String *str, WindowDef *node) } static void -_outConstraint(String *str, Constraint *node) +_outConstraint(String * str, Constraint *node) { if (node->conname) { @@ -2161,7 +2174,7 @@ _outConstraint(String *str, Constraint *node) static void -_outSortBy(String *str, SortBy *node) +_outSortBy(String * str, SortBy *node) { _outNode(str, node->node); @@ -2179,7 +2192,8 @@ _outSortBy(String *str, SortBy *node) string_append_char(str, " NULLS LAST "); } -static void _outInsertStmt(String *str, InsertStmt *node) +static void +_outInsertStmt(String * str, InsertStmt *node) { if (node->withClause) _outWithClause(str, node->withClause); @@ -2192,15 +2206,15 @@ static void _outInsertStmt(String *str, InsertStmt *node) if (node->cols) { - char comma = 0; - ListCell *lc; + char comma = 0; + ListCell *lc; string_append_char(str, "("); - foreach (lc, node->cols) + foreach(lc, node->cols) { - ResTarget *node = lfirst(lc); - ListCell *lc_ind; + ResTarget *node = lfirst(lc); + ListCell *lc_ind; if (comma == 0) comma = 1; @@ -2211,9 +2225,9 @@ static void _outInsertStmt(String *str, InsertStmt *node) string_append_char(str, node->name); string_append_char(str, "\""); - foreach (lc_ind, node->indirection) + foreach(lc_ind, node->indirection) { - Node *ind = lfirst(lc_ind); + Node *ind = lfirst(lc_ind); if (IsA(ind, String)) { @@ -2247,21 +2261,23 @@ static void _outInsertStmt(String *str, InsertStmt *node) } } -static void _outSetClause(String *str, List *node) +static void +_outSetClause(String * str, List *node) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; + + ResTarget *first = linitial(node); - ResTarget *first = linitial(node); string_append_char(str, " SET "); if (IsA(first->val, MultiAssignRef)) { string_append_char(str, "("); - foreach (lc, node) + foreach(lc, node) { - ResTarget *node = lfirst(lc); - ListCell *lc_ind; + ResTarget *node = lfirst(lc); + ListCell *lc_ind; if (comma == 0) comma = 1; @@ -2272,9 +2288,9 @@ static void _outSetClause(String *str, List *node) string_append_char(str, node->name); string_append_char(str, "\""); - foreach (lc_ind, node->indirection) + foreach(lc_ind, node->indirection) { - Node *ind = lfirst(lc_ind); + Node *ind = lfirst(lc_ind); if (IsA(ind, String)) { @@ -2294,10 +2310,10 @@ static void _outSetClause(String *str, List *node) } else { - foreach (lc, node) + foreach(lc, node) { - ResTarget *node = lfirst(lc); - ListCell *lc_ind; + ResTarget *node = lfirst(lc); + ListCell *lc_ind; if (comma == 0) comma = 1; @@ -2308,9 +2324,9 @@ static void _outSetClause(String *str, List *node) string_append_char(str, node->name); string_append_char(str, "\""); - foreach (lc_ind, node->indirection) + foreach(lc_ind, node->indirection) { - Node *ind = lfirst(lc_ind); + Node *ind = lfirst(lc_ind); if (IsA(ind, String)) { @@ -2329,7 +2345,8 @@ static void _outSetClause(String *str, List *node) } } -static void _outUpdateStmt(String *str, UpdateStmt *node) +static void +_outUpdateStmt(String * str, UpdateStmt *node) { if (node->withClause) _outWithClause(str, node->withClause); @@ -2359,7 +2376,8 @@ static void _outUpdateStmt(String *str, UpdateStmt *node) } } -static void _outDeleteStmt(String *str, DeleteStmt *node) +static void +_outDeleteStmt(String * str, DeleteStmt *node) { if (node->withClause) _outWithClause(str, node->withClause); @@ -2387,7 +2405,8 @@ static void _outDeleteStmt(String *str, DeleteStmt *node) } } -static void _outTransactionStmt(String *str, TransactionStmt *node) +static void +_outTransactionStmt(String * str, TransactionStmt *node) { switch (node->kind) { @@ -2443,13 +2462,15 @@ static void _outTransactionStmt(String *str, TransactionStmt *node) } -static void _outTruncateStmt(String *str, TruncateStmt *node) +static void +_outTruncateStmt(String * str, TruncateStmt *node) { string_append_char(str, "TRUNCATE "); _outNode(str, node->relations); } -static void _outVacuumStmt(String *str, VacuumStmt *node) +static void +_outVacuumStmt(String * str, VacuumStmt *node) { if (node->options & VACOPT_VACUUM) string_append_char(str, "VACUUM "); @@ -2477,7 +2498,8 @@ static void _outVacuumStmt(String *str, VacuumStmt *node) } } -static void _outExplainStmt(String *str, ExplainStmt *node) +static void +_outExplainStmt(String * str, ExplainStmt *node) { ListCell *lc; @@ -2519,7 +2541,8 @@ static void _outExplainStmt(String *str, ExplainStmt *node) _outNode(str, node->query); } -static void _outClusterStmt(String *str, ClusterStmt *node) +static void +_outClusterStmt(String * str, ClusterStmt *node) { string_append_char(str, "CLUSTER "); @@ -2533,12 +2556,14 @@ static void _outClusterStmt(String *str, ClusterStmt *node) _outNode(str, node->relation); } -static void _outCheckPointStmt(String *str, CheckPointStmt *node) +static void +_outCheckPointStmt(String * str, CheckPointStmt *node) { string_append_char(str, "CHECKPOINT"); } -static void _outClosePortalStmt(String *str, ClosePortalStmt *node) +static void +_outClosePortalStmt(String * str, ClosePortalStmt *node) { string_append_char(str, "CLOSE "); string_append_char(str, "\""); @@ -2546,7 +2571,8 @@ static void _outClosePortalStmt(String *str, ClosePortalStmt *node) string_append_char(str, "\""); } -static void _outListenStmt(String *str, ListenStmt *node) +static void +_outListenStmt(String * str, ListenStmt *node) { string_append_char(str, "LISTEN "); string_append_char(str, "\""); @@ -2554,28 +2580,32 @@ static void _outListenStmt(String *str, ListenStmt *node) string_append_char(str, "\""); } -static void _outUnlistenStmt(String *str, UnlistenStmt *node) +static void +_outUnlistenStmt(String * str, UnlistenStmt *node) { string_append_char(str, "UNLISTEN "); if (node->conditionname == NULL) string_append_char(str, "*"); - else { + else + { string_append_char(str, "\""); string_append_char(str, node->conditionname); string_append_char(str, "\""); } } -static void _outLoadStmt(String *str, LoadStmt *node) +static void +_outLoadStmt(String * str, LoadStmt *node) { string_append_char(str, "LOAD '"); string_append_char(str, node->filename); string_append_char(str, "'"); } -static void _outCopyStmt(String *str, CopyStmt *node) +static void +_outCopyStmt(String * str, CopyStmt *node) { - ListCell *lc; + ListCell *lc; string_append_char(str, "COPY "); @@ -2611,13 +2641,13 @@ static void _outCopyStmt(String *str, CopyStmt *node) if (server_version_num < 90000) { - foreach (lc, node->options) + foreach(lc, node->options) { - DefElem *e = lfirst(lc); + DefElem *e = lfirst(lc); if (strcmp(e->defname, "format") == 0) { - char *fmt = strVal(e->arg); + char *fmt = strVal(e->arg); if (strcmp(fmt, "text") == 0) ; @@ -2673,9 +2703,9 @@ static void _outCopyStmt(String *str, CopyStmt *node) { string_append_char(str, "("); - foreach (lc, node->options) + foreach(lc, node->options) { - DefElem *e = lfirst(lc); + DefElem *e = lfirst(lc); if (list_head(node->options) != lc) string_append_char(str, ", "); @@ -2714,17 +2744,19 @@ static void _outCopyStmt(String *str, CopyStmt *node) } } -static void _outDeallocateStmt(String *str, DeallocateStmt *node) +static void +_outDeallocateStmt(String * str, DeallocateStmt *node) { string_append_char(str, "DEALLOCATE \""); string_append_char(str, node->name); string_append_char(str, "\""); } -static void _outRenameStmt(String *str, RenameStmt *node) +static void +_outRenameStmt(String * str, RenameStmt *node) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; string_append_char(str, "ALTER "); @@ -2758,12 +2790,14 @@ static void _outRenameStmt(String *str, RenameStmt *node) case OBJECT_FUNCTION: string_append_char(str, "FUNCTION "); - foreach (lc, castNode(List, node->object)) + foreach(lc, castNode(List, node->object)) { - Node *n = lfirst(lc); + Node *n = lfirst(lc); + if (IsA(n, String)) { - Value *value = (Value *) n; + Value *value = (Value *) n; + if (comma == 0) comma = 1; else @@ -2867,14 +2901,14 @@ static void _outRenameStmt(String *str, RenameStmt *node) } static void -_outOptRoleList(String *str, List *options) +_outOptRoleList(String * str, List *options) { - ListCell *lc; + ListCell *lc; - foreach (lc, options) + foreach(lc, options) { - DefElem *elem = lfirst(lc); - Value *value = (Value *) elem->arg; + DefElem *elem = lfirst(lc); + Value *value = (Value *) elem->arg; if (strcmp(elem->defname, "password") == 0) { @@ -2936,7 +2970,7 @@ _outOptRoleList(String *str, List *options) } else if (strcmp(elem->defname, "connectionlimit") == 0) { - char buf[16]; + char buf[16]; string_append_char(str, " CONNECTION LIMIT "); snprintf(buf, 16, "%ld", value->val.ival); @@ -2955,7 +2989,7 @@ _outOptRoleList(String *str, List *options) } else if (strcmp(elem->defname, "sysid") == 0) { - char buf[16]; + char buf[16]; string_append_char(str, " SYSID "); snprintf(buf, 16, "%ld", value->val.ival); @@ -2975,7 +3009,7 @@ _outOptRoleList(String *str, List *options) } static void -_outCreateRoleStmt(String *str, CreateRoleStmt *node) +_outCreateRoleStmt(String * str, CreateRoleStmt *node) { string_append_char(str, "CREATE "); switch (node->stmt_type) @@ -2999,7 +3033,7 @@ _outCreateRoleStmt(String *str, CreateRoleStmt *node) } static void -_outAlterRoleStmt(String *str, AlterRoleStmt *node) +_outAlterRoleStmt(String * str, AlterRoleStmt *node) { string_append_char(str, "ALTER ROLE \""); _outNode(str, node->role); @@ -3010,7 +3044,7 @@ _outAlterRoleStmt(String *str, AlterRoleStmt *node) } static void -_outAlterRoleSetStmt(String *str, AlterRoleSetStmt *node) +_outAlterRoleSetStmt(String * str, AlterRoleSetStmt *node) { string_append_char(str, "ALTER ROLE \""); _outNode(str, node->role); @@ -3022,20 +3056,20 @@ _outAlterRoleSetStmt(String *str, AlterRoleSetStmt *node) } } static void -_outRoleSpec(String *str, RoleSpec *node) +_outRoleSpec(String * str, RoleSpec *node) { string_append_char(str, node->rolename); } static void -_outSetTransactionModeList(String *str, List *list) +_outSetTransactionModeList(String * str, List *list) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; - foreach (lc, list) + foreach(lc, list) { - DefElem *elem = lfirst(lc); + DefElem *elem = lfirst(lc); if (comma == 0) comma = 1; @@ -3044,13 +3078,15 @@ _outSetTransactionModeList(String *str, List *list) if (strcmp(elem->defname, "transaction_isolation") == 0) { - A_Const *v = (A_Const *) elem->arg; + A_Const *v = (A_Const *) elem->arg; + string_append_char(str, " ISOLATION LEVEL "); string_append_char(str, v->val.val.str); } else if (strcmp(elem->defname, "transaction_read_only") == 0) { - A_Const *n = (A_Const *) elem->arg; + A_Const *n = (A_Const *) elem->arg; + if (n->val.val.ival == TRUE) string_append_char(str, "READ ONLY "); else @@ -3061,7 +3097,7 @@ _outSetTransactionModeList(String *str, List *list) static void -_outSetRest(String *str, VariableSetStmt *node) +_outSetRest(String * str, VariableSetStmt *node) { if (strcmp(node->name, "timezone") == 0) { @@ -3101,7 +3137,8 @@ _outSetRest(String *str, VariableSetStmt *node) } else if (strcmp(node->name, "xmloption") == 0) { - A_Const *v = linitial(node->args); + A_Const *v = linitial(node->args); + string_append_char(str, "XML OPTOIN "); string_append_char(str, v->val.val.str); } @@ -3129,7 +3166,7 @@ _outSetRest(String *str, VariableSetStmt *node) } static void -_outDropRoleStmt(String *str, DropRoleStmt *node) +_outDropRoleStmt(String * str, DropRoleStmt *node) { string_append_char(str, "DROP ROLE "); if (node->missing_ok == TRUE) @@ -3138,7 +3175,7 @@ _outDropRoleStmt(String *str, DropRoleStmt *node) } static void -_outCreateSchemaStmt(String *str, CreateSchemaStmt *node) +_outCreateSchemaStmt(String * str, CreateSchemaStmt *node) { string_append_char(str, "CREATE SCHEMA \""); string_append_char(str, node->schemaname); @@ -3153,7 +3190,7 @@ _outCreateSchemaStmt(String *str, CreateSchemaStmt *node) } static void -_outVariableSetStmt(String *str, VariableSetStmt *node) +_outVariableSetStmt(String * str, VariableSetStmt *node) { if (node->kind == VAR_RESET_ALL) { @@ -3173,7 +3210,7 @@ _outVariableSetStmt(String *str, VariableSetStmt *node) } static void -_outVariableShowStmt(String *str, VariableShowStmt *node) +_outVariableShowStmt(String * str, VariableShowStmt *node) { if (strcmp(node->name, "timezone") == 0) string_append_char(str, "SHOW TIME ZONE"); @@ -3191,7 +3228,7 @@ _outVariableShowStmt(String *str, VariableShowStmt *node) } static void -_outConstraintsSetStmt(String *str, ConstraintsSetStmt *node) +_outConstraintsSetStmt(String * str, ConstraintsSetStmt *node) { string_append_char(str, "SET CONSTRAINTS "); @@ -3204,9 +3241,9 @@ _outConstraintsSetStmt(String *str, ConstraintsSetStmt *node) } static void -_outAlterTableCmd(String *str, AlterTableCmd *node) +_outAlterTableCmd(String * str, AlterTableCmd *node) { - char buf[16]; + char buf[16]; switch (node->subtype) { @@ -3379,7 +3416,7 @@ _outAlterTableCmd(String *str, AlterTableCmd *node) } static void -_outAlterTableStmt(String *str, AlterTableStmt *node) +_outAlterTableStmt(String * str, AlterTableStmt *node) { if (node->relkind == OBJECT_TABLE) string_append_char(str, "ALTER TABLE "); @@ -3392,15 +3429,15 @@ _outAlterTableStmt(String *str, AlterTableStmt *node) } static void -_outOptSeqList(String *str, List *options) +_outOptSeqList(String * str, List *options) { - ListCell *lc; + ListCell *lc; - foreach (lc, options) + foreach(lc, options) { - DefElem *e = lfirst(lc); - Value *v = (Value *)e->arg; - char buf[16]; + DefElem *e = lfirst(lc); + Value *v = (Value *) e->arg; + char buf[16]; if (strcmp(e->defname, "cycle") == 0) { @@ -3416,7 +3453,7 @@ _outOptSeqList(String *str, List *options) else if (strcmp(e->defname, "owned_by") == 0) { string_append_char(str, " OWNED BY "); - _outIdList(str, (List *)e->arg); + _outIdList(str, (List *) e->arg); } else { @@ -3445,7 +3482,7 @@ _outOptSeqList(String *str, List *options) } static void -_outCreateSeqStmt(String *str, CreateSeqStmt *node) +_outCreateSeqStmt(String * str, CreateSeqStmt *node) { string_append_char(str, "CREATE "); if (node->sequence->relpersistence == RELPERSISTENCE_TEMP) @@ -3457,7 +3494,7 @@ _outCreateSeqStmt(String *str, CreateSeqStmt *node) } static void -_outAlterSeqStmt(String *str, AlterSeqStmt *node) +_outAlterSeqStmt(String * str, AlterSeqStmt *node) { string_append_char(str, "ALTER SEQUENCE "); _outNode(str, node->sequence); @@ -3465,7 +3502,7 @@ _outAlterSeqStmt(String *str, AlterSeqStmt *node) } static void -_outCreatePLangStmt(String *str, CreatePLangStmt *node) +_outCreatePLangStmt(String * str, CreatePLangStmt *node) { string_append_char(str, "CREATE "); if (node->pltrusted == true) @@ -3476,13 +3513,13 @@ _outCreatePLangStmt(String *str, CreatePLangStmt *node) if (node->plhandler != NIL) { - ListCell *lc; - char dot = 0; + ListCell *lc; + char dot = 0; string_append_char(str, " HANDLER "); - foreach (lc, node->plhandler) + foreach(lc, node->plhandler) { - Value *v = lfirst(lc); + Value *v = lfirst(lc); if (dot == 0) dot = 1; @@ -3497,13 +3534,13 @@ _outCreatePLangStmt(String *str, CreatePLangStmt *node) if (node->plvalidator != NIL) { - ListCell *lc; - char dot = 0; + ListCell *lc; + char dot = 0; string_append_char(str, " VALIDATOR "); - foreach (lc, node->plvalidator) + foreach(lc, node->plvalidator) { - Value *v = lfirst(lc); + Value *v = lfirst(lc); if (dot == 0) dot = 1; @@ -3519,7 +3556,7 @@ _outCreatePLangStmt(String *str, CreatePLangStmt *node) static void -_outCreateTableSpaceStmt(String *str, CreateTableSpaceStmt *node) +_outCreateTableSpaceStmt(String * str, CreateTableSpaceStmt *node) { string_append_char(str, "CREATE TABLESPACE \""); string_append_char(str, node->tablespacename); @@ -3538,7 +3575,7 @@ _outCreateTableSpaceStmt(String *str, CreateTableSpaceStmt *node) } static void -_outDropTableSpaceStmt(String *str, DropTableSpaceStmt *node) +_outDropTableSpaceStmt(String * str, DropTableSpaceStmt *node) { string_append_char(str, "DROP TABLESPACE \""); string_append_char(str, node->tablespacename); @@ -3546,16 +3583,16 @@ _outDropTableSpaceStmt(String *str, DropTableSpaceStmt *node) } static void -_outFuncName(String *str, List *func_name) +_outFuncName(String * str, List *func_name) { - ListCell *lc; - Value *v; - char dot = 0; + ListCell *lc; + Value *v; + char dot = 0; if (func_name == NULL) return; - foreach (lc, func_name) + foreach(lc, func_name) { v = (Value *) lfirst(lc); @@ -3578,9 +3615,9 @@ _outFuncName(String *str, List *func_name) } static void -_outCreateTrigStmt(String *str, CreateTrigStmt *node) +_outCreateTrigStmt(String * str, CreateTrigStmt *node) { - bool has_events = false; + bool has_events = false; if (node->isconstraint == TRUE) string_append_char(str, "CREATE CONSTRAINT TRIGGER \""); @@ -3649,18 +3686,18 @@ _outCreateTrigStmt(String *str, CreateTrigStmt *node) } static void -_outDefinition(String *str, List *definition) +_outDefinition(String * str, List *definition) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; if (definition == NIL) return; string_append_char(str, "("); - foreach (lc, definition) + foreach(lc, definition) { - DefElem *e = lfirst(lc); + DefElem *e = lfirst(lc); if (comma == 0) comma = 1; @@ -3681,10 +3718,10 @@ _outDefinition(String *str, List *definition) } static void -_outDefineStmt(String *str, DefineStmt *node) +_outDefineStmt(String * str, DefineStmt *node) { - ListCell *lc; - char dot = 0; + ListCell *lc; + char dot = 0; switch (node->kind) { @@ -3698,9 +3735,9 @@ _outDefineStmt(String *str, DefineStmt *node) case OBJECT_OPERATOR: string_append_char(str, "CREATE OPERATOR "); - foreach (lc, node->defnames) + foreach(lc, node->defnames) { - Value *v = lfirst(lc); + Value *v = lfirst(lc); if (dot == 0) dot = 1; @@ -3751,14 +3788,14 @@ _outDefineStmt(String *str, DefineStmt *node) } static void -_outOperatorName(String *str, List *list) +_outOperatorName(String * str, List *list) { - char dot = 0; - ListCell *lc; + char dot = 0; + ListCell *lc; - foreach (lc, list) + foreach(lc, list) { - Value *v = lfirst(lc); + Value *v = lfirst(lc); if (dot == 0) dot = 1; @@ -3770,9 +3807,9 @@ _outOperatorName(String *str, List *list) } static void -_outCreateOpClassItem(String *str, CreateOpClassItem *node) +_outCreateOpClassItem(String * str, CreateOpClassItem *node) { - char buf[16]; + char buf[16]; switch (node->itemtype) { @@ -3789,10 +3826,10 @@ _outCreateOpClassItem(String *str, CreateOpClassItem *node) _outNode(str, node->name->objname); string_append_char(str, ")"); } + /* - if (node->recheck == TRUE) - string_append_char(str, " RECHECK"); - */ + * if (node->recheck == TRUE) string_append_char(str, " RECHECK"); + */ break; case OPCLASS_ITEM_FUNCTION: @@ -3818,7 +3855,7 @@ _outCreateOpClassItem(String *str, CreateOpClassItem *node) } static void -_outCreateOpClassStmt(String *str, CreateOpClassStmt *node) +_outCreateOpClassStmt(String * str, CreateOpClassStmt *node) { string_append_char(str, "CREATE OPERATOR CLASS "); _outFuncName(str, node->opclassname); @@ -3845,17 +3882,18 @@ _outCreateOpClassStmt(String *str, CreateOpClassStmt *node) * OPERATOR, DROP OPERATOR CLASS */ -static void add_function_like_objs(String *str, DropStmt *node) +static void +add_function_like_objs(String * str, DropStmt *node) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; if (node->concurrent) string_append_char(str, "CONCURRENTLY "); if (node->missing_ok) string_append_char(str, "IF EXISTS "); - foreach (lc, node->objects) + foreach(lc, node->objects) { if (comma == 0) comma = 1; @@ -3866,9 +3904,9 @@ static void add_function_like_objs(String *str, DropStmt *node) } static void -_outDropStmt(String *str, DropStmt *node) +_outDropStmt(String * str, DropStmt *node) { - List *objname; + List *objname; string_append_char(str, "DROP "); switch (node->removeType) @@ -3965,7 +4003,7 @@ _outDropStmt(String *str, DropStmt *node) objname = lfirst(list_head(node->objects)); string_append_char(str, strVal(llast(objname))); string_append_char(str, " ON "); - string_append_char(str, NameListToString(list_truncate(list_copy(objname), + string_append_char(str, NameListToString(list_truncate(list_copy(objname), list_length(objname) - 1))); break; @@ -4018,9 +4056,9 @@ _outDropStmt(String *str, DropStmt *node) } static void -_outFetchStmt(String *str, FetchStmt *node) +_outFetchStmt(String * str, FetchStmt *node) { - char buf[16]; + char buf[16]; snprintf(buf, 16, "%ld", node->howMany); @@ -4079,18 +4117,18 @@ _outFetchStmt(String *str, FetchStmt *node) } static void -_outPrivilegeList(String *str, List *list) +_outPrivilegeList(String * str, List *list) { - ListCell *lc; - char comma = 0; + ListCell *lc; + char comma = 0; if (list == NIL) string_append_char(str, "ALL"); else { - foreach (lc, list) + foreach(lc, list) { - Value *v = lfirst(lc); + Value *v = lfirst(lc); if (comma == 0) comma = 1; @@ -4103,7 +4141,7 @@ _outPrivilegeList(String *str, List *list) } static void -_outFunctionParameter(String *str, FunctionParameter *node) +_outFunctionParameter(String * str, FunctionParameter *node) { switch (node->mode) { @@ -4131,7 +4169,7 @@ _outFunctionParameter(String *str, FunctionParameter *node) } static void -_outObjectWithArgs(String *str, ObjectWithArgs *node) +_outObjectWithArgs(String * str, ObjectWithArgs *node) { _outFuncName(str, node->objname); string_append_char(str, "("); @@ -4140,7 +4178,7 @@ _outObjectWithArgs(String *str, ObjectWithArgs *node) } static void -_outGrantStmt(String *str, GrantStmt *node) +_outGrantStmt(String * str, GrantStmt *node) { if (node->is_grant == true) string_append_char(str, "GRANT "); @@ -4201,11 +4239,11 @@ _outGrantStmt(String *str, GrantStmt *node) _outIdList(str, node->objects); break; - case ACL_OBJECT_COLUMN: - case ACL_OBJECT_DOMAIN: - case ACL_OBJECT_LARGEOBJECT: - case ACL_OBJECT_TYPE: - break; + case ACL_OBJECT_COLUMN: + case ACL_OBJECT_DOMAIN: + case ACL_OBJECT_LARGEOBJECT: + case ACL_OBJECT_TYPE: + break; } if (node->is_grant == true) @@ -4222,7 +4260,7 @@ _outGrantStmt(String *str, GrantStmt *node) } static void -_outGrantRoleStmt(String *str, GrantRoleStmt *node) +_outGrantRoleStmt(String * str, GrantRoleStmt *node) { if (node->is_grant == true) string_append_char(str, "GRANT "); @@ -4254,14 +4292,14 @@ _outGrantRoleStmt(String *str, GrantRoleStmt *node) } static void -_outFuncOptList(String *str, List *list) +_outFuncOptList(String * str, List *list) { - ListCell *lc; + ListCell *lc; - foreach (lc, list) + foreach(lc, list) { - DefElem *e = lfirst(lc); - Value *v = (Value *) e->arg; + DefElem *e = lfirst(lc); + Value *v = (Value *) e->arg; if (strcmp(e->defname, "strict") == 0) { @@ -4272,7 +4310,8 @@ _outFuncOptList(String *str, List *list) } else if (strcmp(e->defname, "volatility") == 0) { - char *s = v->val.str; + char *s = v->val.str; + if (strcmp(s, "immutable") == 0) string_append_char(str, " IMMUTABLE"); else if (strcmp(s, "stable") == 0) @@ -4302,7 +4341,7 @@ _outFuncOptList(String *str, List *list) } static void -_outCreateFunctionStmt(String *str, CreateFunctionStmt *node) +_outCreateFunctionStmt(String * str, CreateFunctionStmt *node) { string_append_char(str, "CREATE "); if (node->replace == true) @@ -4331,7 +4370,7 @@ _outCreateFunctionStmt(String *str, CreateFunctionStmt *node) } static void -_outAlterFunctionStmt(String *str, AlterFunctionStmt *node) +_outAlterFunctionStmt(String * str, AlterFunctionStmt *node) { string_append_char(str, "ALTER FUNCTION "); _outNode(str, node->func); @@ -4340,7 +4379,7 @@ _outAlterFunctionStmt(String *str, AlterFunctionStmt *node) static void -_outCreateCastStmt(String *str, CreateCastStmt *node) +_outCreateCastStmt(String * str, CreateCastStmt *node) { string_append_char(str, "CREATE CAST ("); _outNode(str, node->sourcetype); @@ -4365,7 +4404,7 @@ _outCreateCastStmt(String *str, CreateCastStmt *node) } static void -_outReindexStmt(String *str, ReindexStmt *node) +_outReindexStmt(String * str, ReindexStmt *node) { string_append_char(str, "REINDEX "); @@ -4403,7 +4442,7 @@ _outReindexStmt(String *str, ReindexStmt *node) } static void -_outAlterObjectSchemaStmt(String *str, AlterObjectSchemaStmt *node) +_outAlterObjectSchemaStmt(String * str, AlterObjectSchemaStmt *node) { string_append_char(str, "ALTER "); @@ -4471,11 +4510,11 @@ _outAlterObjectSchemaStmt(String *str, AlterObjectSchemaStmt *node) } static void -_outAlterOwnerStmt(String *str, AlterOwnerStmt *node) +_outAlterOwnerStmt(String * str, AlterOwnerStmt *node) { string_append_char(str, "ALTER "); - ObjectWithArgs *owa = castNode(ObjectWithArgs, node); + ObjectWithArgs *owa = castNode(ObjectWithArgs, node); switch (node->objectType) { @@ -4625,7 +4664,7 @@ _outAlterOwnerStmt(String *str, AlterOwnerStmt *node) } static void -_outRuleStmt(String *str, RuleStmt *node) +_outRuleStmt(String * str, RuleStmt *node) { string_append_char(str, "CREATE "); if (node->replace) @@ -4676,12 +4715,12 @@ _outRuleStmt(String *str, RuleStmt *node) _outNode(str, linitial(node->actions)); else { - ListCell *lc; - char semi = 0; + ListCell *lc; + char semi = 0; string_append_char(str, "("); - foreach (lc, node->actions) + foreach(lc, node->actions) { if (semi == 0) semi = 1; @@ -4696,7 +4735,7 @@ _outRuleStmt(String *str, RuleStmt *node) } static void -_outViewStmt(String *str, ViewStmt *node) +_outViewStmt(String * str, ViewStmt *node) { if (node->replace) string_append_char(str, "CREATE OR REPLACE "); @@ -4721,15 +4760,15 @@ _outViewStmt(String *str, ViewStmt *node) } static void -_outCreatedbOptList(String *str, List *options) +_outCreatedbOptList(String * str, List *options) { - ListCell *lc; + ListCell *lc; - foreach (lc, options) + foreach(lc, options) { - DefElem *e = lfirst(lc); - Value *v = (Value *) e->arg; - int sconst = false; + DefElem *e = lfirst(lc); + Value *v = (Value *) e->arg; + int sconst = false; /* keyword */ if (strcmp(e->defname, "template") == 0) @@ -4754,7 +4793,7 @@ _outCreatedbOptList(String *str, List *options) /* value */ if (v == NULL) string_append_char(str, "DEFAULT"); - else if (IsA((Node *)v, String)) + else if (IsA((Node *) v, String)) { string_append_char(str, sconst ? "'" : "'"); string_append_char(str, v->val.str); @@ -4762,7 +4801,8 @@ _outCreatedbOptList(String *str, List *options) } else { - char buf[16]; + char buf[16]; + snprintf(buf, 16, "%ld", v->val.ival); string_append_char(str, buf); } @@ -4770,7 +4810,7 @@ _outCreatedbOptList(String *str, List *options) } static void -_outCreatedbStmt(String *str, CreatedbStmt *node) +_outCreatedbStmt(String * str, CreatedbStmt *node) { string_append_char(str, "CREATE DATABASE \""); string_append_char(str, node->dbname); @@ -4780,7 +4820,7 @@ _outCreatedbStmt(String *str, CreatedbStmt *node) } static void -_outAlterDatabaseStmt(String *str, AlterDatabaseStmt *node) +_outAlterDatabaseStmt(String * str, AlterDatabaseStmt *node) { string_append_char(str, "ALTER DATABASE \""); string_append_char(str, node->dbname); @@ -4790,7 +4830,7 @@ _outAlterDatabaseStmt(String *str, AlterDatabaseStmt *node) } static void -_outAlterDatabaseSetStmt(String *str, AlterDatabaseSetStmt *node) +_outAlterDatabaseSetStmt(String * str, AlterDatabaseSetStmt *node) { string_append_char(str, "ALTER DATABASE \""); string_append_char(str, node->dbname); @@ -4800,7 +4840,7 @@ _outAlterDatabaseSetStmt(String *str, AlterDatabaseSetStmt *node) } static void -_outDropdbStmt(String *str, DropdbStmt *node) +_outDropdbStmt(String * str, DropdbStmt *node) { string_append_char(str, "DROP DATABASE \""); string_append_char(str, node->dbname); @@ -4808,9 +4848,9 @@ _outDropdbStmt(String *str, DropdbStmt *node) } static void -_outCreateDomainStmt(String *str, CreateDomainStmt *node) +_outCreateDomainStmt(String * str, CreateDomainStmt *node) { - ListCell *lc; + ListCell *lc; string_append_char(str, "CREATE DOMAIN "); _outFuncName(str, node->domainname); @@ -4818,7 +4858,7 @@ _outCreateDomainStmt(String *str, CreateDomainStmt *node) _outNode(str, node->typeName); - foreach (lc, node->constraints) + foreach(lc, node->constraints) { string_append_char(str, " "); _outNode(str, lfirst(lc)); @@ -4826,7 +4866,7 @@ _outCreateDomainStmt(String *str, CreateDomainStmt *node) } static void -_outAlterDomainStmt(String *str, AlterDomainStmt *node) +_outAlterDomainStmt(String * str, AlterDomainStmt *node) { string_append_char(str, "ALTER DOMAIN "); _outFuncName(str, node->typeName); @@ -4867,7 +4907,7 @@ _outAlterDomainStmt(String *str, AlterDomainStmt *node) } static void -_outCreateConversionStmt(String *str, CreateConversionStmt *node) +_outCreateConversionStmt(String * str, CreateConversionStmt *node) { string_append_char(str, "CREATE "); @@ -4887,7 +4927,7 @@ _outCreateConversionStmt(String *str, CreateConversionStmt *node) } static void -_outPrepareStmt(String *str, PrepareStmt *node) +_outPrepareStmt(String * str, PrepareStmt *node) { string_append_char(str, "PREPARE \""); string_append_char(str, node->name); @@ -4905,7 +4945,7 @@ _outPrepareStmt(String *str, PrepareStmt *node) } static void -_outExecuteStmt(String *str, ExecuteStmt *node) +_outExecuteStmt(String * str, ExecuteStmt *node) { string_append_char(str, "EXECUTE \""); string_append_char(str, node->name); @@ -4920,7 +4960,7 @@ _outExecuteStmt(String *str, ExecuteStmt *node) } static void -_outLockStmt(String *str, LockStmt *node) +_outLockStmt(String * str, LockStmt *node) { string_append_char(str, "LOCK TABLE "); _outNode(str, node->relations); @@ -4967,9 +5007,10 @@ _outLockStmt(String *str, LockStmt *node) } static void -_outOperatorArgTypes(String *str, List *args) +_outOperatorArgTypes(String * str, List *args) { - TypeName *left, *right; + TypeName *left, + *right; left = linitial(args); right = lsecond(args); @@ -4986,15 +5027,15 @@ _outOperatorArgTypes(String *str, List *args) } static void -_outCommentStmt(String *str, CommentStmt *node) +_outCommentStmt(String * str, CommentStmt *node) { - TypeName *t; - Value *v; - char buf[16]; + TypeName *t; + Value *v; + char buf[16]; string_append_char(str, "COMMENT ON "); - ObjectWithArgs *owa = castNode(ObjectWithArgs, node); + ObjectWithArgs *owa = castNode(ObjectWithArgs, node); switch (node->objtype) { @@ -5021,7 +5062,7 @@ _outCommentStmt(String *str, CommentStmt *node) case OBJECT_OPERATOR: string_append_char(str, "OPERATOR "); - _outOperatorName(str, owa->objname); + _outOperatorName(str, owa->objname); string_append_char(str, "("); _outOperatorArgTypes(str, owa->objargs); string_append_char(str, ")"); @@ -5134,7 +5175,7 @@ _outCommentStmt(String *str, CommentStmt *node) } static void -_outRangeSubselect(String *str, RangeSubselect *node) +_outRangeSubselect(String * str, RangeSubselect *node) { string_append_char(str, "("); _outNode(str, node->subquery); @@ -5145,10 +5186,11 @@ _outRangeSubselect(String *str, RangeSubselect *node) /*TODO*/ static void -_outRangeFunction(String *str, RangeFunction *node) +_outRangeFunction(String * str, RangeFunction *node) { - _outNode(str, node->functions); //TODO - if (node->alias) + _outNode(str, node->functions); + //TODO + if (node->alias) { _outNode(str, node->alias); } @@ -5162,7 +5204,7 @@ _outRangeFunction(String *str, RangeFunction *node) } static void -_outRangeTableSample(String *str, RangeTableSample *node) +_outRangeTableSample(String * str, RangeTableSample *node) { _outNode(str, node->relation); string_append_char(str, " TABLESAMPLE "); @@ -5171,7 +5213,8 @@ _outRangeTableSample(String *str, RangeTableSample *node) _outNode(str, node->args); string_append_char(str, ")"); - if (node->repeatable) { + if (node->repeatable) + { string_append_char(str, " REPEATABLE ("); _outNode(str, node->repeatable); string_append_char(str, ")"); @@ -5179,17 +5222,17 @@ _outRangeTableSample(String *str, RangeTableSample *node) } static void -_outRangeTableFunc(String *str, RangeTableFunc *node) +_outRangeTableFunc(String * str, RangeTableFunc *node) { } static void -_outRangeTableFuncCol(String *str, RangeTableFuncCol *node) +_outRangeTableFuncCol(String * str, RangeTableFuncCol *node) { } static void -_outDiscardStmt(String *str, DiscardStmt *node) +_outDiscardStmt(String * str, DiscardStmt *node) { switch (node->target) { @@ -5211,7 +5254,7 @@ _outDiscardStmt(String *str, DiscardStmt *node) } static void -_outCreateOpFamilyStmt(String *str, CreateOpFamilyStmt *node) +_outCreateOpFamilyStmt(String * str, CreateOpFamilyStmt *node) { string_append_char(str, "CREATE OPERATOR FAMILY "); _outIdList(str, node->opfamilyname); @@ -5221,12 +5264,12 @@ _outCreateOpFamilyStmt(String *str, CreateOpFamilyStmt *node) } static void -_outAlterOpFamilyStmt(String *str, AlterOpFamilyStmt *node) +_outAlterOpFamilyStmt(String * str, AlterOpFamilyStmt *node) { } static void -_outCreateEnumStmt(String *str, CreateEnumStmt *node) +_outCreateEnumStmt(String * str, CreateEnumStmt *node) { string_append_char(str, "CREATE TYPE "); _outIdList(str, node->typeName); @@ -5236,7 +5279,7 @@ _outCreateEnumStmt(String *str, CreateEnumStmt *node) } static void -_outDropOwnedStmt(String *str, DropOwnedStmt *node) +_outDropOwnedStmt(String * str, DropOwnedStmt *node) { string_append_char(str, "DROP OWNED BY "); _outIdList(str, node->roles); @@ -5245,7 +5288,7 @@ _outDropOwnedStmt(String *str, DropOwnedStmt *node) } static void -_outReassignOwnedStmt(String *str, ReassignOwnedStmt *node) +_outReassignOwnedStmt(String * str, ReassignOwnedStmt *node) { string_append_char(str, "REASSIGN OWNED BY "); _outIdList(str, node->roles); @@ -5255,7 +5298,7 @@ _outReassignOwnedStmt(String *str, ReassignOwnedStmt *node) } static void -_outAlterTSDictionaryStmt(String *str, AlterTSDictionaryStmt *node) +_outAlterTSDictionaryStmt(String * str, AlterTSDictionaryStmt *node) { string_append_char(str, "ALTER TEXT SEARCH DICTIONARY "); _outIdList(str, node->dictname); @@ -5265,7 +5308,7 @@ _outAlterTSDictionaryStmt(String *str, AlterTSDictionaryStmt *node) } static void -_outAlterTSConfigurationStmt(String *str, AlterTSConfigurationStmt *node) +_outAlterTSConfigurationStmt(String * str, AlterTSConfigurationStmt *node) { string_append_char(str, "ALTER TEXT SEARCH CONFIGURATION "); _outIdList(str, node->cfgname); @@ -5310,9 +5353,9 @@ _outAlterTSConfigurationStmt(String *str, AlterTSConfigurationStmt *node) } static void -_outXmlExpr(String *str, XmlExpr *node) +_outXmlExpr(String * str, XmlExpr *node) { - A_Const *n; + A_Const *n; switch (node->op) { @@ -5364,7 +5407,7 @@ _outXmlExpr(String *str, XmlExpr *node) _outNode(str, linitial(node->args)); n = lsecond(node->args); { - Node *arg = ((TypeCast *) n)->arg; + Node *arg = ((TypeCast *) n)->arg; if (((A_Const *) arg)->val.val.str[0] == 't') string_append_char(str, " PRESERVE WHITESPACE"); @@ -5380,24 +5423,25 @@ _outXmlExpr(String *str, XmlExpr *node) } static void -_outXmlSerialize(String *str, XmlSerialize *node) +_outXmlSerialize(String * str, XmlSerialize *node) { } static void -_outWithDefinition(String *str, List *def_list) +_outWithDefinition(String * str, List *def_list) { - int oid = 0; + int oid = 0; if (list_length(def_list) == 1) { - DefElem *elem; + DefElem *elem; elem = linitial(def_list); if (strcmp(elem->defname, "oids") == 0) { - Value *v = (Value *)elem->arg; + Value *v = (Value *) elem->arg; + if (v->val.ival == 1) string_append_char(str, " WITH OIDS "); else @@ -5414,7 +5458,7 @@ _outWithDefinition(String *str, List *def_list) } static void -_outOnConflictClause(String *str, OnConflictClause *node) +_outOnConflictClause(String * str, OnConflictClause *node) { string_append_char(str, " ON CONFLICT "); @@ -5462,22 +5506,22 @@ _outOnConflictClause(String *str, OnConflictClause *node) } static void -_outPartitionElem(String *str, PartitionElem *node) +_outPartitionElem(String * str, PartitionElem *node) { } static void -_outPartitionSpec(String *str, PartitionSpec *node) +_outPartitionSpec(String * str, PartitionSpec *node) { } static void -_outPartitionBoundSpec(String *str, PartitionBoundSpec *node) +_outPartitionBoundSpec(String * str, PartitionBoundSpec *node) { } static void -_outPartitionRangeDatum(String *str, PartitionRangeDatum *node) +_outPartitionRangeDatum(String * str, PartitionRangeDatum *node) { } @@ -5486,7 +5530,7 @@ _outPartitionRangeDatum(String *str, PartitionRangeDatum *node) * converts a Node into ascii string and append it to 'str' */ void -_outNode(String *str, void *obj) +_outNode(String * str, void *obj) { if (obj == NULL) return; @@ -5510,11 +5554,10 @@ _outNode(String *str, void *obj) case T_RangeVar: _outRangeVar(str, obj); break; + /* - case T_IntoClause: - _outIntoClause(str, obj); - break; - */ + * case T_IntoClause: _outIntoClause(str, obj); break; + */ case T_Var: _outVar(str, obj); break; @@ -5530,11 +5573,10 @@ _outNode(String *str, void *obj) case T_GroupingFunc: _outGroupingFunc(str, obj); break; + /* - case T_WindowFunc: - _outWindowFunc(str, obj); - break; - */ + * case T_WindowFunc: _outWindowFunc(str, obj); break; + */ case T_ArrayRef: _outArrayRef(str, obj); break; @@ -5565,11 +5607,11 @@ _outNode(String *str, void *obj) case T_SubPlan: _outSubPlan(str, obj); break; + /* - case T_AlternativeSubPlan: - _outAlternativeSubPlan(str, obj); - break; - */ + * case T_AlternativeSubPlan: _outAlternativeSubPlan(str, + * obj); break; + */ case T_FieldSelect: _outFieldSelect(str, obj); break; @@ -5579,22 +5621,18 @@ _outNode(String *str, void *obj) case T_RelabelType: _outRelabelType(str, obj); break; + /* - case T_CoerceViaIO: - _outCoerceViaIO(str, obj); - break; - case T_ArrayCoerceExpr: - _outArrayCoerceExpr(str, obj); - break; - */ + * case T_CoerceViaIO: _outCoerceViaIO(str, obj); break; case + * T_ArrayCoerceExpr: _outArrayCoerceExpr(str, obj); break; + */ case T_ConvertRowtypeExpr: _outConvertRowtypeExpr(str, obj); break; + /* - case T_CollateExpr: - _outCollateExpr(str, obj); - break; - */ + * case T_CollateExpr: _outCollateExpr(str, obj); break; + */ case T_CaseExpr: _outCaseExpr(str, obj); break; @@ -5610,21 +5648,20 @@ _outNode(String *str, void *obj) case T_RowExpr: _outRowExpr(str, obj); break; + /* - case T_RowCompareExpr: - _outRowCompareExpr(str, obj); - break; - */ + * case T_RowCompareExpr: _outRowCompareExpr(str, obj); break; + */ case T_CoalesceExpr: _outCoalesceExpr(str, obj); break; case T_MinMaxExpr: _outMinMaxExpr(str, obj); break; + /* - case T_SQLValueFunction: - _outSQLValueFunction(str, obj); - */ + * case T_SQLValueFunction: _outSQLValueFunction(str, obj); + */ break; case T_XmlExpr: _outXmlExpr(str, obj); @@ -5647,11 +5684,10 @@ _outNode(String *str, void *obj) case T_CurrentOfExpr: _outCurrentOfExpr(str, obj); break; + /* - case T_NextValueExpr: - _outNextValueExpr(str, obj); - break; - */ + * case T_NextValueExpr: _outNextValueExpr(str, obj); break; + */ case T_InferenceElem: _outInferenceElem(str, obj); break; @@ -5717,28 +5753,21 @@ _outNode(String *str, void *obj) case T_IndexElem: _outIndexElem(str, obj); break; + /* - case T_Query: - _outQuery(str, obj); - break; - case T_WithCheckOption: - _outWithCheckOption(str, obj); - break; - case T_SortGroupClause: - _outSortGroupClause(str, obj); - break; - */ + * case T_Query: _outQuery(str, obj); break; case + * T_WithCheckOption: _outWithCheckOption(str, obj); break; + * case T_SortGroupClause: _outSortGroupClause(str, obj); + * break; + */ case T_GroupingSet: _outGroupingSet(str, obj); break; + /* - case T_WindowClause: - _outWindowClause(str, obj); - break; - case T_RowMarkClause: - _outRowMarkClause(str, obj); - break; - */ + * case T_WindowClause: _outWindowClause(str, obj); break; + * case T_RowMarkClause: _outRowMarkClause(str, obj); break; + */ case T_WithClause: _outWithClause(str, obj); break; @@ -5748,11 +5777,10 @@ _outNode(String *str, void *obj) case T_SetOperationStmt: _outSetOperationStmt(str, obj); break; - /* - case T_RangeTblEntry: - _outRangeTblEntry(str, obj); - break; - */ + + /* + * case T_RangeTblEntry: _outRangeTblEntry(str, obj); break; + */ case T_TableSampleClause: _outTableSampleClause(str, obj); break; @@ -5768,11 +5796,10 @@ _outNode(String *str, void *obj) case T_A_Const: _outAConst(str, obj); break; + /* - case T_A_Star: - _outA_Star(str, obj); - break; - */ + * case T_A_Star: _outA_Star(str, obj); break; + */ case T_A_Indices: _outA_Indices(str, obj); break; @@ -5818,11 +5845,11 @@ _outNode(String *str, void *obj) case T_DefElem: _outDefElem(str, obj); break; + /* - case T_TableLikeClause: - _outTableLikeClause(str, obj); - break; - */ + * case T_TableLikeClause: _outTableLikeClause(str, obj); + * break; + */ case T_LockingClause: _outLockingClause(str, obj); break; @@ -6138,17 +6165,16 @@ _outNode(String *str, void *obj) char * nodeToString(const void *obj) { - String *str; - char *p; + String *str; + char *p; str = init_string(""); - _outNode(str, (void *)obj); - p = palloc(str->len+1); + _outNode(str, (void *) obj); + p = palloc(str->len + 1); memcpy(p, str->data, str->len); - *(p+str->len) = '\0'; + *(p + str->len) = '\0'; free_string(str); return p; } - diff --git a/src/parser/parser.c b/src/parser/parser.c index 6d0f2391b..2ded1ed93 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -23,17 +23,17 @@ #include <string.h> #include "pool_parser.h" #include "utils/palloc.h" -#include "gramparse.h" /* required before parser/gram.h! */ +#include "gramparse.h" /* required before parser/gram.h! */ #include "gram.h" #include "parser.h" #include "pg_wchar.h" #include "utils/elog.h" -int server_version_num = 0; +int server_version_num = 0; static pg_enc server_encoding = PG_SQL_ASCII; static int -parse_version(const char *versionString); + parse_version(const char *versionString); /* @@ -51,7 +51,7 @@ raw_parser(const char *str, bool *error) base_yy_extra_type yyextra; int yyresult; - MemoryContext oldContext = CurrentMemoryContext; + MemoryContext oldContext = CurrentMemoryContext; /* initialize error flag */ *error = false; @@ -99,8 +99,8 @@ raw_parser(const char *str, bool *error) Node * raw_parser2(List *parse_tree_list) { - Node *node = NULL; - RawStmt *rstmt; + Node *node = NULL; + RawStmt *rstmt; rstmt = (RawStmt *) lfirst(list_head(parse_tree_list)); node = (Node *) rstmt->stmt; @@ -245,8 +245,8 @@ parse_version(const char *versionString) { int cnt; int vmaj, - vmin, - vrev; + vmin, + vrev; cnt = sscanf(versionString, "%d.%d.%d", &vmaj, &vmin, &vrev); @@ -293,4 +293,3 @@ pg_mblen(const char *mbstr) { return pg_utf_mblen((const unsigned char *) mbstr); } - diff --git a/src/parser/pool_string.c b/src/parser/pool_string.c index 427f12c7d..c6df2590f 100644 --- a/src/parser/pool_string.c +++ b/src/parser/pool_string.c @@ -27,12 +27,13 @@ #include "value.h" /* String Library */ -String *init_string(char *str) +String * +init_string(char *str) { - String *string = palloc(sizeof(String)); - int size; + String *string = palloc(sizeof(String)); + int size; - string->len = (str != NULL)? strlen(str): 0; + string->len = (str != NULL) ? strlen(str) : 0; size = (string->len + 1) / STRING_SIZE + 1; string->size = size; @@ -42,24 +43,28 @@ String *init_string(char *str) if (str != NULL) memcpy(string->data, str, string->len); - + return string; } -void string_append_string(String *string, String *data) +void +string_append_string(String * string, String * data) { string_append_char(string, data->data); } -void string_append_char(String *string, char *append_data) +void +string_append_char(String * string, char *append_data) { - int len = strlen(append_data); - + int len = strlen(append_data); + if (string->len + len + 1 > string->size * STRING_SIZE) { - int size, old_size; + int size, + old_size; + size = (string->len + len + 1) / STRING_SIZE + 1; - old_size = string->size; + old_size = string->size; string->size = size; string->data = repalloc(string->data, string->size * STRING_SIZE); memset(string->data + (old_size * STRING_SIZE), @@ -69,20 +74,22 @@ void string_append_char(String *string, char *append_data) string->len += len; } -void free_string(String *string) +void +free_string(String * string) { pfree(string->data); pfree(string); } -String *copy_string(String *string) +String * +copy_string(String * string) { - String *copy = palloc(sizeof(String)); + String *copy = palloc(sizeof(String)); copy->size = string->size; copy->len = string->len; copy->data = palloc(string->size * STRING_SIZE); memcpy(copy->data, string->data, string->size * STRING_SIZE); - + return copy; } diff --git a/src/pcp_con/pcp_child.c b/src/pcp_con/pcp_child.c index 5c919fbfb..7a6cfbff4 100644 --- a/src/pcp_con/pcp_child.c +++ b/src/pcp_con/pcp_child.c @@ -59,11 +59,12 @@ #include "utils/elog.h" #include "parser/pg_list.h" -static int pcp_unix_fd, pcp_inet_fd; +static int pcp_unix_fd, + pcp_inet_fd; volatile bool *pcp_recovery_in_progress; static volatile sig_atomic_t pcp_got_sighup = 0; static volatile sig_atomic_t pcp_restart_request = 0; -List *pcp_worker_children = NULL; +List *pcp_worker_children = NULL; static volatile sig_atomic_t sigchld_request = 0; static RETSIGTYPE pcp_exit_handler(int sig); @@ -72,7 +73,7 @@ static RETSIGTYPE reload_config_handler(int sig); static RETSIGTYPE restart_handler(int sig); static RETSIGTYPE reap_handler(int sig); -static int pcp_do_accept(int unix_fd, int inet_fd); +static int pcp_do_accept(int unix_fd, int inet_fd); static void start_pcp_command_processor_process(int port); static void pcp_child_will_die(int code, Datum arg); static void pcp_kill_all_children(int sig); @@ -96,7 +97,8 @@ static void reaper(void); /* * main entry point for pcp child process */ -void pcp_main(int unix_fd, int inet_fd) +void +pcp_main(int unix_fd, int inet_fd) { sigjmp_buf local_sigjmp_buf; struct timeval uptime; @@ -110,10 +112,11 @@ void pcp_main(int unix_fd, int inet_fd) pcp_recovery_in_progress = pool_shared_memory_create(sizeof(bool)); *pcp_recovery_in_progress = false; + /* * install the call back for preparation of exit */ - on_system_exit(pcp_child_will_die, (Datum)NULL); + on_system_exit(pcp_child_will_die, (Datum) NULL); /* set up signal handlers */ pool_signal(SIGTERM, pcp_exit_handler); @@ -142,16 +145,17 @@ void pcp_main(int unix_fd, int inet_fd) PG_exception_stack = &local_sigjmp_buf; ereport(DEBUG1, - (errmsg("I am PCP child with pid:%d",getpid()))); + (errmsg("I am PCP child with pid:%d", getpid()))); - for(;;) + for (;;) { - int port; + int port; + errno = 0; CHECK_RESTART_REQUEST; port = pcp_do_accept(unix_fd, inet_fd); - if(port > 0) + if (port > 0) { start_pcp_command_processor_process(port); } @@ -161,12 +165,12 @@ void pcp_main(int unix_fd, int inet_fd) static int pcp_do_accept(int unix_fd, int inet_fd) { - fd_set readmask; - int fds; + fd_set readmask; + int fds; struct sockaddr addr; - socklen_t addrlen; - int fd = 0; - int afd; + socklen_t addrlen; + int fd = 0; + int afd; int inet = 0; set_ps_display("PCP: wait for connection request", false); @@ -176,14 +180,14 @@ pcp_do_accept(int unix_fd, int inet_fd) if (inet_fd) FD_SET(inet_fd, &readmask); - fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, NULL); + fds = select(Max(unix_fd, inet_fd) + 1, &readmask, NULL, NULL, NULL); if (fds == -1) { if (errno == EAGAIN || errno == EINTR) return -1; ereport(ERROR, (errmsg("unable to accept new pcp connection"), - errdetail("select system call failed with error : \"%s\"",strerror(errno)))); + errdetail("select system call failed with error : \"%s\"", strerror(errno)))); } if (FD_ISSET(unix_fd, &readmask)) { @@ -192,7 +196,7 @@ pcp_do_accept(int unix_fd, int inet_fd) if (FD_ISSET(inet_fd, &readmask)) { fd = inet_fd; - inet++; + inet ++; } addrlen = sizeof(addr); @@ -201,17 +205,18 @@ pcp_do_accept(int unix_fd, int inet_fd) if (afd < 0) { /* - * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) - * can be silently ignored. + * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) can be + * silently ignored. */ if (errno != EAGAIN && errno != EWOULDBLOCK) ereport(ERROR, (errmsg("unable to accept new pcp connection"), - errdetail("socket accept system call failed with error : \"%s\"",strerror(errno)))); + errdetail("socket accept system call failed with error : \"%s\"", strerror(errno)))); } if (pcp_got_sighup) { MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); MemoryContextSwitchTo(oldContext); pcp_got_sighup = 0; @@ -220,7 +225,8 @@ pcp_do_accept(int unix_fd, int inet_fd) (errmsg("I am PCP child with PID:%d and accept fd:%d", getpid(), afd))); if (inet) { - int on = 1; + int on = 1; + if (setsockopt(afd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) @@ -228,7 +234,7 @@ pcp_do_accept(int unix_fd, int inet_fd) close(afd); ereport(ERROR, (errmsg("unable to accept new pcp connection"), - errdetail("setsockopt system call failed with error : \"%s\"",strerror(errno)))); + errdetail("setsockopt system call failed with error : \"%s\"", strerror(errno)))); } if (setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, @@ -237,7 +243,7 @@ pcp_do_accept(int unix_fd, int inet_fd) close(afd); ereport(ERROR, (errmsg("unable to accept new pcp connection"), - errdetail("setsockopt system call failed with error : \"%s\"",strerror(errno)))); + errdetail("setsockopt system call failed with error : \"%s\"", strerror(errno)))); } } return afd; @@ -246,10 +252,12 @@ pcp_do_accept(int unix_fd, int inet_fd) /* * forks a new pcp worker child */ -static void start_pcp_command_processor_process(int port) +static void +start_pcp_command_processor_process(int port) { - pid_t pid = fork(); - if (pid == 0)/* child */ + pid_t pid = fork(); + + if (pid == 0) /* child */ { /* Set the process type variable */ processType = PT_PCP_WORKER; @@ -260,16 +268,16 @@ static void start_pcp_command_processor_process(int port) /* call PCP child main */ if (pcp_worker_children) list_free(pcp_worker_children); - pcp_worker_children= NULL; + pcp_worker_children = NULL; POOL_SETMASK(&UnBlockSig); - pcp_worker_main(port); /* Never returns */ + pcp_worker_main(port); /* Never returns */ } else if (pid == -1) { ereport(FATAL, (errmsg("fork() failed. reason: %s", strerror(errno)))); } - else /* parent */ + else /* parent */ { ereport(LOG, (errmsg("forked new pcp worker, pid=%d socket=%d", @@ -277,7 +285,7 @@ static void start_pcp_command_processor_process(int port) /* close the port in parent process. It is only consumed by child */ close(port); /* Add it to the list */ - pcp_worker_children = lappend_int(pcp_worker_children, (int)pid); + pcp_worker_children = lappend_int(pcp_worker_children, (int) pid); } } @@ -288,13 +296,16 @@ static void pcp_kill_all_children(int sig) { /* forward wakeup requests to children */ - ListCell* lc; + ListCell *lc; + foreach(lc, pcp_worker_children) { - pid_t pid = (pid_t)lfirst_int(lc); - kill(pid,sig); + pid_t pid = (pid_t) lfirst_int(lc); + + kill(pid, sig); } } + /* * handle SIGCHLD */ @@ -305,10 +316,11 @@ static RETSIGTYPE reap_handler(int sig) POOL_SETMASK(&UnBlockSig); } -static void reaper(void) +static void +reaper(void) { - pid_t pid; - int status; + pid_t pid; + int status; ereport(DEBUG1, (errmsg("PCP child reaper handler"))); @@ -318,9 +330,9 @@ static void reaper(void) while ((pid = pool_waitpid(&status)) > 0) { - if(WIFEXITED(status)) + if (WIFEXITED(status)) { - if(WEXITSTATUS(status) == POOL_EXIT_FATAL) + if (WEXITSTATUS(status) == POOL_EXIT_FATAL) ereport(LOG, (errmsg("PCP worker process with pid: %d exit with FATAL ERROR.", pid))); else @@ -330,35 +342,35 @@ static void reaper(void) if (WIFSIGNALED(status)) { /* Child terminated by segmentation fault. Report it */ - if(WTERMSIG(status) == SIGSEGV) + if (WTERMSIG(status) == SIGSEGV) ereport(WARNING, - (errmsg("PCP process with pid: %d was terminated by segmentation fault",pid))); + (errmsg("PCP process with pid: %d was terminated by segmentation fault", pid))); else ereport(LOG, (errmsg("PCP process with pid: %d exits with status %d by signal %d", pid, status, WTERMSIG(status)))); } else ereport(LOG, - (errmsg("PCP process with pid: %d exits with status %d",pid, status))); + (errmsg("PCP process with pid: %d exits with status %d", pid, status))); ereport(DEBUG2, - (errmsg("going to remove pid: %d from pid list having %d elements",pid, list_length(pcp_worker_children)))); + (errmsg("going to remove pid: %d from pid list having %d elements", pid, list_length(pcp_worker_children)))); /* remove the pid of process from the list */ - pcp_worker_children = list_delete_int(pcp_worker_children,pid); + pcp_worker_children = list_delete_int(pcp_worker_children, pid); ereport(DEBUG2, - (errmsg("new list have %d elements",list_length(pcp_worker_children)))); + (errmsg("new list have %d elements", list_length(pcp_worker_children)))); } } static RETSIGTYPE pcp_exit_handler(int sig) { - pid_t wpid; + pid_t wpid; POOL_SETMASK(&AuthBlockSig); pcp_kill_all_children(sig); - if (sig == SIGTERM) /* smart shutdown */ + if (sig == SIGTERM) /* smart shutdown */ { /* close the listening sockets */ close(pcp_unix_fd); @@ -372,8 +384,8 @@ pcp_exit_handler(int sig) do { wpid = wait(NULL); - }while (wpid > 0 || (wpid == -1 && errno == EINTR)); - + } while (wpid > 0 || (wpid == -1 && errno == EINTR)); + list_free(pcp_worker_children); } pcp_worker_children = NULL; @@ -401,13 +413,15 @@ static RETSIGTYPE reload_config_handler(int sig) pcp_got_sighup = 1; } -static void pcp_child_will_die(int code, Datum arg) +static void +pcp_child_will_die(int code, Datum arg) { - pid_t wpid; + pid_t wpid; + /* * This is supposed to be called from main process */ - if(processType != PT_PCP) + if (processType != PT_PCP) return; if (list_length(pcp_worker_children) <= 0) return; @@ -416,12 +430,12 @@ static void pcp_child_will_die(int code, Datum arg) do { wpid = wait(NULL); - }while (wpid > 0 || (wpid == -1 && errno == EINTR)); - + } while (wpid > 0 || (wpid == -1 && errno == EINTR)); + if (wpid == -1 && errno != ECHILD) ereport(WARNING, (errmsg("wait() on pcp worker children failed. reason:%s", strerror(errno)))); - + POOL_SETMASK(&UnBlockSig); } @@ -430,14 +444,16 @@ static void pcp_child_will_die(int code, Datum arg) * is in progress. If the flag is already set the function returns * false. */ -bool pcp_mark_recovery_in_progress(void) +bool +pcp_mark_recovery_in_progress(void) { - bool command_already_inprogress; + bool command_already_inprogress; pool_sigset_t oldmask; - /* + + /* * only pcp worker is allowd to make this call */ - if(processType != PT_PCP_WORKER) + if (processType != PT_PCP_WORKER) return false; POOL_SETMASK2(&BlockSig, &oldmask); @@ -453,13 +469,15 @@ bool pcp_mark_recovery_in_progress(void) * unsets the shared memory flag to indicate pcp recovery command * is finsihed. */ -void pcp_mark_recovery_finished(void) +void +pcp_mark_recovery_finished(void) { pool_sigset_t oldmask; + /* * only pcp worker is allowd to make this call */ - if(processType != PT_PCP_WORKER) + if (processType != PT_PCP_WORKER) return; POOL_SETMASK2(&BlockSig, &oldmask); @@ -468,4 +486,3 @@ void pcp_mark_recovery_finished(void) pool_semaphore_unlock(PCP_REQUEST_SEM); POOL_SETMASK(&oldmask); } - diff --git a/src/pcp_con/pcp_worker.c b/src/pcp_con/pcp_worker.c index 10ac9cb3b..2bf91f699 100644 --- a/src/pcp_con/pcp_worker.c +++ b/src/pcp_con/pcp_worker.c @@ -52,41 +52,42 @@ #define MAX_FILE_LINE_LEN 512 -extern char *pcp_conf_file; /* global variable defined in main.c holds the path for pcp.conf */ +extern char *pcp_conf_file; /* global variable defined in main.c holds the + * path for pcp.conf */ volatile sig_atomic_t pcp_worker_wakeup_request = 0; -PCP_CONNECTION* volatile pcp_frontend = NULL; +PCP_CONNECTION *volatile pcp_frontend = NULL; static RETSIGTYPE die(int sig); static RETSIGTYPE wakeup_handler_child(int sig); static void unset_nonblock(int fd); -static int user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len); -static void process_authentication(PCP_CONNECTION *frontend, char *buf, char* salt, int *random_salt); -static void send_md5salt(PCP_CONNECTION *frontend, char* salt); +static int user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len); +static void process_authentication(PCP_CONNECTION * frontend, char *buf, char *salt, int *random_salt); +static void send_md5salt(PCP_CONNECTION * frontend, char *salt); static void pcp_process_command(char tos, char *buf, int buf_len); -static int pool_detach_node(int node_id, bool gracefully); -static int pool_promote_node(int node_id, bool gracefully); -static void inform_process_count(PCP_CONNECTION *frontend); -static void inform_process_info(PCP_CONNECTION *frontend, char *buf); -static void inform_watchdog_info(PCP_CONNECTION *frontend, char *buf); -static void inform_node_info(PCP_CONNECTION *frontend, char *buf); -static void inform_node_count(PCP_CONNECTION *frontend); -static void process_detach_node(PCP_CONNECTION *frontend,char *buf,char tos); -static void process_attach_node(PCP_CONNECTION *frontend,char *buf); -static void process_recovery_request(PCP_CONNECTION *frontend,char *buf); -static void process_status_request(PCP_CONNECTION *frontend); -static void process_promote_node(PCP_CONNECTION *frontend,char *buf, char tos); -static void process_shutown_request(PCP_CONNECTION *frontend,char mode); -static void process_set_configration_parameter(PCP_CONNECTION *frontend,char *buf, int len); +static int pool_detach_node(int node_id, bool gracefully); +static int pool_promote_node(int node_id, bool gracefully); +static void inform_process_count(PCP_CONNECTION * frontend); +static void inform_process_info(PCP_CONNECTION * frontend, char *buf); +static void inform_watchdog_info(PCP_CONNECTION * frontend, char *buf); +static void inform_node_info(PCP_CONNECTION * frontend, char *buf); +static void inform_node_count(PCP_CONNECTION * frontend); +static void process_detach_node(PCP_CONNECTION * frontend, char *buf, char tos); +static void process_attach_node(PCP_CONNECTION * frontend, char *buf); +static void process_recovery_request(PCP_CONNECTION * frontend, char *buf); +static void process_status_request(PCP_CONNECTION * frontend); +static void process_promote_node(PCP_CONNECTION * frontend, char *buf, char tos); +static void process_shutown_request(PCP_CONNECTION * frontend, char mode); +static void process_set_configration_parameter(PCP_CONNECTION * frontend, char *buf, int len); static void pcp_worker_will_go_down(int code, Datum arg); -static void do_pcp_flush(PCP_CONNECTION *frontend); -static void do_pcp_read(PCP_CONNECTION *pc, void *buf, int len); +static void do_pcp_flush(PCP_CONNECTION * frontend); +static void do_pcp_read(PCP_CONNECTION * pc, void *buf, int len); -/* +/* * main entry pont of pcp worker child process */ void @@ -96,15 +97,15 @@ pcp_worker_main(int port) MemoryContext PCPMemoryContext; volatile int authenticated = 0; - char salt[4]; - int random_salt = 0; + char salt[4]; + int random_salt = 0; struct timeval uptime; - char tos; - int rsize; - char *buf = NULL; + char tos; + int rsize; + char *buf = NULL; ereport(DEBUG1, - (errmsg("I am PCP worker child with pid:%d",getpid()))); + (errmsg("I am PCP worker child with pid:%d", getpid()))); /* Identify myself via ps */ init_ps_display("", "", "", ""); @@ -134,11 +135,11 @@ pcp_worker_main(int port) /* * install the call back for preparation of pcp worker child exit */ - on_system_exit(pcp_worker_will_go_down, (Datum)NULL); + on_system_exit(pcp_worker_will_go_down, (Datum) NULL); /* Initialize my backend status */ pool_initialize_private_backend_status(); - + /* Initialize process context */ pool_init_process_context(); @@ -155,8 +156,8 @@ pcp_worker_main(int port) } /* We can now handle ereport(ERROR) */ PG_exception_stack = &local_sigjmp_buf; - - for(;;) + + for (;;) { MemoryContextSwitchTo(PCPMemoryContext); MemoryContextResetAndDeleteChildren(PCPMemoryContext); @@ -171,37 +172,37 @@ pcp_worker_main(int port) if (rsize <= 0 || rsize >= MAX_PCP_PACKET_LENGTH) ereport(FATAL, - (errmsg("invalid PCP packet"), + (errmsg("invalid PCP packet"), errdetail("incorrect packet length (%d)", rsize))); if ((rsize - sizeof(int)) > 0) { - buf = (char *)palloc(rsize - sizeof(int)); + buf = (char *) palloc(rsize - sizeof(int)); do_pcp_read(pcp_frontend, buf, rsize - sizeof(int)); } ereport(DEBUG1, - (errmsg("received PCP packet"), + (errmsg("received PCP packet"), errdetail("PCP packet type of service '%c'", tos))); - if (tos == 'R') /* authentication */ + if (tos == 'R') /* authentication */ { set_ps_display("PCP: processing authentication", false); - process_authentication(pcp_frontend, buf,salt, &random_salt); + process_authentication(pcp_frontend, buf, salt, &random_salt); authenticated = 1; continue; } - if (tos == 'M') /* md5 salt */ + if (tos == 'M') /* md5 salt */ { set_ps_display("PCP: processing authentication", false); send_md5salt(pcp_frontend, salt); random_salt = 1; continue; } - /* is this connection authenticated? if not disconnect immediately*/ + /* is this connection authenticated? if not disconnect immediately */ if (!authenticated) ereport(FATAL, - (errmsg("authentication failed for new PCP connection"), + (errmsg("authentication failed for new PCP connection"), errdetail("connection not authorized"))); /* process a request */ @@ -221,11 +222,12 @@ pcp_process_command(char tos, char *buf, int buf_len) { if (Req_info->switching) { - if(Req_info->request_queue_tail != Req_info->request_queue_head) + if (Req_info->request_queue_tail != Req_info->request_queue_head) { POOL_REQUEST_KIND reqkind; - reqkind = Req_info->request[(Req_info->request_queue_head +1) % MAX_REQUEST_QUEUE_SIZE].kind; - + + reqkind = Req_info->request[(Req_info->request_queue_head + 1) % MAX_REQUEST_QUEUE_SIZE].kind; + if (reqkind == NODE_UP_REQUEST) ereport(ERROR, (errmsg("failed to process PCP request at the moment"), @@ -245,46 +247,46 @@ pcp_process_command(char tos, char *buf, int buf_len) } } } - + switch (tos) { - case 'A': /* set configuration parameter */ + case 'A': /* set configuration parameter */ set_ps_display("PCP: processing set configration parameter request", false); - process_set_configration_parameter(pcp_frontend,buf,buf_len); + process_set_configration_parameter(pcp_frontend, buf, buf_len); break; - case 'L': /* node count */ + case 'L': /* node count */ set_ps_display("PCP: processing node count request", false); inform_node_count(pcp_frontend); break; - case 'I': /* node info */ + case 'I': /* node info */ set_ps_display("PCP: processing node info request", false); inform_node_info(pcp_frontend, buf); break; - case 'N': /* process count */ + case 'N': /* process count */ set_ps_display("PCP: processing process count request", false); inform_process_count(pcp_frontend); break; - case 'P': /* process info */ + case 'P': /* process info */ set_ps_display("PCP: processing process info request", false); inform_process_info(pcp_frontend, buf); break; - case 'W': /* watchdog info */ + case 'W': /* watchdog info */ set_ps_display("PCP: processing watchdog info request", false); inform_watchdog_info(pcp_frontend, buf); break; - case 'D': /* detach node */ - case 'd': /* detach node gracefully */ + case 'D': /* detach node */ + case 'd': /* detach node gracefully */ set_ps_display("PCP: processing detach node request", false); process_detach_node(pcp_frontend, buf, tos); break; - case 'C': /* attach node */ + case 'C': /* attach node */ set_ps_display("PCP: processing attach node request", false); process_attach_node(pcp_frontend, buf); break; @@ -294,20 +296,20 @@ pcp_process_command(char tos, char *buf, int buf_len) process_shutown_request(pcp_frontend, buf[0]); break; - case 'O': /* recovery request */ + case 'O': /* recovery request */ set_ps_display("PCP: processing recovery request", false); process_recovery_request(pcp_frontend, buf); break; - case 'B': /* status request*/ + case 'B': /* status request */ set_ps_display("PCP: processing status request request", false); process_status_request(pcp_frontend); break; - case 'J': /* promote node */ - case 'j': /* promote node gracefully */ + case 'J': /* promote node */ + case 'j': /* promote node gracefully */ set_ps_display("PCP: processing promote node request", false); - process_promote_node(pcp_frontend,buf,tos); + process_promote_node(pcp_frontend, buf, tos); break; case 'F': @@ -315,9 +317,9 @@ pcp_process_command(char tos, char *buf, int buf_len) (errmsg("PCP processing request, stop online recovery"))); break; - case 'X': /* disconnect */ + case 'X': /* disconnect */ ereport(DEBUG1, - (errmsg("PCP processing request, client disconnecting"), + (errmsg("PCP processing request, client disconnecting"), errdetail("closing PCP connection, and exiting child"))); pcp_close(pcp_frontend); pcp_frontend = NULL; @@ -327,8 +329,8 @@ pcp_process_command(char tos, char *buf, int buf_len) default: ereport(FATAL, - (errmsg("PCP processing request"), - errdetail("unknown PCP packet type \"%c\"",tos))); + (errmsg("PCP processing request"), + errdetail("unknown PCP packet type \"%c\"", tos))); } } @@ -337,11 +339,11 @@ die(int sig) { ereport(DEBUG1, (errmsg("PCP worker child receives shutdown request signal %d", sig))); - if(sig == SIGTERM) + if (sig == SIGTERM) { ereport(DEBUG1, - (errmsg("PCP worker child receives smart shutdown request."), - errdetail("waiting for the child to die its natural death"))); + (errmsg("PCP worker child receives smart shutdown request."), + errdetail("waiting for the child to die its natural death"))); } else if (sig == SIGINT) { @@ -372,22 +374,22 @@ wakeup_handler_child(int sig) static void unset_nonblock(int fd) { - int var; - + int var; + /* set fd to non-blocking */ var = fcntl(fd, F_GETFL, 0); if (var == -1) { ereport(FATAL, (errmsg("unable to connect"), - errdetail("fcntl system call failed with error : \"%s\"",strerror(errno)))); - + errdetail("fcntl system call failed with error : \"%s\"", strerror(errno)))); + } if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1) { ereport(FATAL, (errmsg("unable to connect"), - errdetail("fcntl system call failed with error : \"%s\"",strerror(errno)))); + errdetail("fcntl system call failed with error : \"%s\"", strerror(errno)))); } } @@ -397,28 +399,29 @@ unset_nonblock(int fd) static int user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) { - FILE *fp = NULL; - char packet_username[MAX_USER_PASSWD_LEN+1]; - char packet_password[MAX_USER_PASSWD_LEN+1]; - char encrypt_buf[(MD5_PASSWD_LEN+1)*2]; - char file_username[MAX_USER_PASSWD_LEN+1]; - char file_password[MAX_USER_PASSWD_LEN+1]; - char *index = NULL; - static char line[MAX_FILE_LINE_LEN+1]; - int i, len; - + FILE *fp = NULL; + char packet_username[MAX_USER_PASSWD_LEN + 1]; + char packet_password[MAX_USER_PASSWD_LEN + 1]; + char encrypt_buf[(MD5_PASSWD_LEN + 1) * 2]; + char file_username[MAX_USER_PASSWD_LEN + 1]; + char file_password[MAX_USER_PASSWD_LEN + 1]; + char *index = NULL; + static char line[MAX_FILE_LINE_LEN + 1]; + int i, + len; + /* strcpy() should be OK, but use strncpy() to be extra careful */ strncpy(packet_username, buf, MAX_USER_PASSWD_LEN); index = (char *) memchr(buf, '\0', MAX_USER_PASSWD_LEN); if (index == NULL) { ereport(FATAL, - (errmsg("failed to authenticate PCP user"), + (errmsg("failed to authenticate PCP user"), errdetail("error while reading authentication packet"))); return 0; } strncpy(packet_password, ++index, MAX_USER_PASSWD_LEN); - + fp = fopen(passwd_file, "r"); if (fp == NULL) { @@ -427,7 +430,7 @@ user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) errdetail("could not open %s. reason: %s", passwd_file, strerror(errno)))); return 0; } - + /* for now, I don't care if duplicate username exists in the config file */ while ((fgets(line, MAX_FILE_LINE_LEN, fp)) != NULL) { @@ -444,7 +447,7 @@ user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) { fclose(fp); ereport(FATAL, - (errmsg("failed to authenticate PCP user"), + (errmsg("failed to authenticate PCP user"), errdetail("username read from file \"%s\" is larger than maximum allowed username length [%d]", passwd_file, MAX_USER_PASSWD_LEN))); return 0; } @@ -464,21 +467,21 @@ user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) { fclose(fp); ereport(FATAL, - (errmsg("failed to authenticate PCP user"), + (errmsg("failed to authenticate PCP user"), errdetail("password read from file \"%s\" is larger than maximum allowed password length [%d]", passwd_file, MAX_USER_PASSWD_LEN))); return 0; } } - memcpy(file_password, line+strlen(file_username)+1, len); + memcpy(file_password, line + strlen(file_username) + 1, len); file_password[len] = '\0'; pool_md5_encrypt(file_password, file_username, strlen(file_username), - encrypt_buf + MD5_PASSWD_LEN + 1); - encrypt_buf[(MD5_PASSWD_LEN+1)*2-1] = '\0'; + encrypt_buf + MD5_PASSWD_LEN + 1); + encrypt_buf[(MD5_PASSWD_LEN + 1) * 2 - 1] = '\0'; - pool_md5_encrypt(encrypt_buf+MD5_PASSWD_LEN+1, salt, salt_len, - encrypt_buf); + pool_md5_encrypt(encrypt_buf + MD5_PASSWD_LEN + 1, salt, salt_len, + encrypt_buf); encrypt_buf[MD5_PASSWD_LEN] = '\0'; if (strcmp(encrypt_buf, packet_password) == 0) @@ -489,7 +492,7 @@ user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) } fclose(fp); ereport(FATAL, - (errmsg("authentication failed for user \"%s\"",packet_username), + (errmsg("authentication failed for user \"%s\"", packet_username), errdetail("username and/or password does not match"))); return 0; @@ -497,7 +500,8 @@ user_authenticate(char *buf, char *passwd_file, char *salt, int salt_len) /* Detach a node */ -static int pool_detach_node(int node_id, bool gracefully) +static int +pool_detach_node(int node_id, bool gracefully) { if (!gracefully) { @@ -505,8 +509,8 @@ static int pool_detach_node(int node_id, bool gracefully) return 0; } - /* Check if the NODE DOWN can be executed on - * the given node id. + /* + * Check if the NODE DOWN can be executed on the given node id. */ degenerate_backend_set_ex(&node_id, 1, REQ_DETAIL_SWITCHOVER | REQ_DETAIL_CONFIRMED, true, true); @@ -537,32 +541,34 @@ static int pool_detach_node(int node_id, bool gracefully) while (!pcp_worker_wakeup_request) { struct timeval t = {1, 0}; + select(0, NULL, NULL, NULL, &t); } pcp_worker_wakeup_request = 0; /* - * Start to accept incoming connections and send SIGUSR2 to pgpool - * parent to distribute SIGUSR2 all pgpool children. + * Start to accept incoming connections and send SIGUSR2 to pgpool parent + * to distribute SIGUSR2 all pgpool children. */ finish_recovery(); - + return 0; } /* Promote a node */ -static int pool_promote_node(int node_id, bool gracefully) +static int +pool_promote_node(int node_id, bool gracefully) { if (!gracefully) { - promote_backend(node_id, REQ_DETAIL_CONFIRMED); /* send promote request */ + promote_backend(node_id, REQ_DETAIL_CONFIRMED); /* send promote request */ return 0; } /* * Wait until all frontends exit */ - *InRecovery = RECOVERY_PROMOTE; /* This wiil ensure that new incoming + *InRecovery = RECOVERY_PROMOTE; /* This wiil ensure that new incoming * connection requests are blocked */ if (wait_connection_closed()) @@ -575,7 +581,7 @@ static int pool_promote_node(int node_id, bool gracefully) /* * Now all frontends have gone. Let's do failover. */ - promote_backend(node_id, REQ_DETAIL_CONFIRMED); /* send promote request */ + promote_backend(node_id, REQ_DETAIL_CONFIRMED); /* send promote request */ /* * Wait for failover completed. @@ -585,52 +591,55 @@ static int pool_promote_node(int node_id, bool gracefully) while (!pcp_worker_wakeup_request) { struct timeval t = {1, 0}; + select(0, NULL, NULL, NULL, &t); } pcp_worker_wakeup_request = 0; /* - * Start to accept incoming connections and send SIGUSR2 to pgpool - * parent to distribute SIGUSR2 all pgpool children. + * Start to accept incoming connections and send SIGUSR2 to pgpool parent + * to distribute SIGUSR2 all pgpool children. */ finish_recovery(); return 0; } static void -inform_process_count(PCP_CONNECTION *frontend) +inform_process_count(PCP_CONNECTION * frontend) { - int wsize; - int process_count; - char process_count_str[16]; - int *process_list = NULL; - char code[] = "CommandComplete"; - char *mesg = NULL; - int i; - int total_port_len = 0; + int wsize; + int process_count; + char process_count_str[16]; + int *process_list = NULL; + char code[] = "CommandComplete"; + char *mesg = NULL; + int i; + int total_port_len = 0; process_list = pool_get_process_list(&process_count); - mesg = (char *)palloc(7*process_count); /* PID is at most 6 characters long */ + mesg = (char *) palloc(7 * process_count); /* PID is at most 6 characters + * long */ snprintf(process_count_str, sizeof(process_count_str), "%d", process_count); for (i = 0; i < process_count; i++) { - char process_id[7]; + char process_id[7]; + snprintf(process_id, sizeof(process_id), "%d", process_list[i]); - snprintf(mesg+total_port_len, strlen(process_id)+1, "%s", process_id); - total_port_len += strlen(process_id)+1; + snprintf(mesg + total_port_len, strlen(process_id) + 1, "%s", process_id); + total_port_len += strlen(process_id) + 1; } pcp_write(frontend, "n", 1); wsize = htonl(sizeof(code) + - strlen(process_count_str)+1 + + strlen(process_count_str) + 1 + total_port_len + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, process_count_str, strlen(process_count_str)+1); + pcp_write(frontend, process_count_str, strlen(process_count_str) + 1); pcp_write(frontend, mesg, total_port_len); do_pcp_flush(frontend); @@ -638,33 +647,34 @@ inform_process_count(PCP_CONNECTION *frontend) pfree(mesg); ereport(DEBUG1, - (errmsg("PCP: informing process count"), + (errmsg("PCP: informing process count"), errdetail("%d process(es) found", process_count))); } static void -inform_process_info(PCP_CONNECTION *frontend,char *buf) +inform_process_info(PCP_CONNECTION * frontend, char *buf) { - int proc_id; - int wsize; - int num_proc = pool_config->num_init_children; - int i; + int proc_id; + int wsize; + int num_proc = pool_config->num_init_children; + int i; proc_id = atoi(buf); if ((proc_id != 0) && (pool_get_process_info(proc_id) == NULL)) { ereport(ERROR, - (errmsg("informing process info failed"), - errdetail("invalid process ID : %s",buf))); + (errmsg("informing process info failed"), + errdetail("invalid process ID : %s", buf))); } else { /* First, send array size of connection_info */ - char arr_code[] = "ArraySize"; - char con_info_size[16]; + char arr_code[] = "ArraySize"; + char con_info_size[16]; + /* Finally, indicate that all data is sent */ - char fin_code[] = "CommandComplete"; + char fin_code[] = "CommandComplete"; POOL_REPORT_POOLS *pools = get_pools(&num_proc); @@ -679,28 +689,29 @@ inform_process_info(PCP_CONNECTION *frontend,char *buf) pcp_write(frontend, "p", 1); wsize = htonl(sizeof(arr_code) + - strlen(con_info_size)+1 + + strlen(con_info_size) + 1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, arr_code, sizeof(arr_code)); - pcp_write(frontend, con_info_size, strlen(con_info_size)+1); + pcp_write(frontend, con_info_size, strlen(con_info_size) + 1); do_pcp_flush(frontend); /* Second, send process information for all connection_info */ - for (i=0; i<num_proc; i++) + for (i = 0; i < num_proc; i++) { - char code[] = "ProcessInfo"; - char proc_pid[16]; - char proc_start_time[20]; - char proc_create_time[20]; - char majorversion[5]; - char minorversion[5]; - char pool_counter[16]; - char backend_id[16]; - char backend_pid[16]; - char connected[2]; - - if (proc_id != 0 && proc_id != pools[i].pool_pid) continue; + char code[] = "ProcessInfo"; + char proc_pid[16]; + char proc_start_time[20]; + char proc_create_time[20]; + char majorversion[5]; + char minorversion[5]; + char pool_counter[16]; + char backend_id[16]; + char backend_pid[16]; + char connected[2]; + + if (proc_id != 0 && proc_id != pools[i].pool_pid) + continue; snprintf(proc_pid, sizeof(proc_pid), "%d", pools[i].pool_pid); snprintf(proc_start_time, sizeof(proc_start_time), "%ld", pools[i].start_time); @@ -713,32 +724,32 @@ inform_process_info(PCP_CONNECTION *frontend,char *buf) snprintf(connected, sizeof(connected), "%d", pools[i].pool_connected); pcp_write(frontend, "p", 1); - wsize = htonl( sizeof(code) + - strlen(proc_pid)+1 + - strlen(pools[i].database)+1 + - strlen(pools[i].username)+1 + - strlen(proc_start_time)+1 + - strlen(proc_create_time)+1 + - strlen(majorversion)+1 + - strlen(minorversion)+1 + - strlen(pool_counter)+1 + - strlen(backend_id)+1 + - strlen(backend_pid)+1 + - strlen(connected)+1 + + wsize = htonl(sizeof(code) + + strlen(proc_pid) + 1 + + strlen(pools[i].database) + 1 + + strlen(pools[i].username) + 1 + + strlen(proc_start_time) + 1 + + strlen(proc_create_time) + 1 + + strlen(majorversion) + 1 + + strlen(minorversion) + 1 + + strlen(pool_counter) + 1 + + strlen(backend_id) + 1 + + strlen(backend_pid) + 1 + + strlen(connected) + 1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, proc_pid, strlen(proc_pid)+1); - pcp_write(frontend, pools[i].database, strlen(pools[i].database)+1); - pcp_write(frontend, pools[i].username, strlen(pools[i].username)+1); - pcp_write(frontend, proc_start_time, strlen(proc_start_time)+1); - pcp_write(frontend, proc_create_time, strlen(proc_create_time)+1); - pcp_write(frontend, majorversion, strlen(majorversion)+1); - pcp_write(frontend, minorversion, strlen(minorversion)+1); - pcp_write(frontend, pool_counter, strlen(pool_counter)+1); - pcp_write(frontend, backend_id, strlen(backend_id)+1); - pcp_write(frontend, backend_pid, strlen(backend_pid)+1); - pcp_write(frontend, connected, strlen(connected)+1); + pcp_write(frontend, proc_pid, strlen(proc_pid) + 1); + pcp_write(frontend, pools[i].database, strlen(pools[i].database) + 1); + pcp_write(frontend, pools[i].username, strlen(pools[i].username) + 1); + pcp_write(frontend, proc_start_time, strlen(proc_start_time) + 1); + pcp_write(frontend, proc_create_time, strlen(proc_create_time) + 1); + pcp_write(frontend, majorversion, strlen(majorversion) + 1); + pcp_write(frontend, minorversion, strlen(minorversion) + 1); + pcp_write(frontend, pool_counter, strlen(pool_counter) + 1); + pcp_write(frontend, backend_id, strlen(backend_id) + 1); + pcp_write(frontend, backend_pid, strlen(backend_pid) + 1); + pcp_write(frontend, connected, strlen(connected) + 1); do_pcp_flush(frontend); } @@ -751,23 +762,23 @@ inform_process_info(PCP_CONNECTION *frontend,char *buf) ereport(DEBUG1, (errmsg("PCP informing process info"), errdetail("retrieved process information from shared memory"))); - + pfree(pools); } } static void -inform_watchdog_info(PCP_CONNECTION *frontend,char *buf) +inform_watchdog_info(PCP_CONNECTION * frontend, char *buf) { - int wd_index; - int json_data_len; - int wsize; - char code[] = "CommandComplete"; - char* json_data; + int wd_index; + int json_data_len; + int wsize; + char code[] = "CommandComplete"; + char *json_data; if (!pool_config->use_watchdog) ereport(ERROR, - (errmsg("PCP: informing watchdog info failed"), + (errmsg("PCP: informing watchdog info failed"), errdetail("watcdhog is not enabled"))); wd_index = atoi(buf); @@ -775,45 +786,44 @@ inform_watchdog_info(PCP_CONNECTION *frontend,char *buf) json_data = wd_get_watchdog_nodes(wd_index); if (json_data == NULL) ereport(ERROR, - (errmsg("PCP: informing watchdog info failed"), + (errmsg("PCP: informing watchdog info failed"), errdetail("invalid watchdog index"))); ereport(DEBUG2, - (errmsg("PCP: informing watchdog info"), + (errmsg("PCP: informing watchdog info"), errdetail("retrieved node information from IPC socket"))); /* - * This is the voilation of PCP protocol but I think - * in future we should shift to more adaptable protocol for - * data transmition. + * This is the voilation of PCP protocol but I think in future we should + * shift to more adaptable protocol for data transmition. */ json_data_len = strlen(json_data); wsize = htonl(sizeof(code) + - json_data_len+ 1 + + json_data_len + 1 + sizeof(int)); pcp_write(frontend, "w", 1); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, json_data, json_data_len +1); + pcp_write(frontend, json_data, json_data_len + 1); do_pcp_flush(frontend); pfree(json_data); } static void -inform_node_info(PCP_CONNECTION *frontend,char *buf) +inform_node_info(PCP_CONNECTION * frontend, char *buf) { - int node_id; - int wsize; - char port_str[6]; - char status[2]; - char weight_str[20]; - char role_str[10]; - char standby_delay_str[20]; - char status_changed_time_str[20]; - char code[] = "CommandComplete"; + int node_id; + int wsize; + char port_str[6]; + char status[2]; + char weight_str[20]; + char role_str[10]; + char standby_delay_str[20]; + char status_changed_time_str[20]; + char code[] = "CommandComplete"; BackendInfo *bi = NULL; SERVER_ROLE role; @@ -825,11 +835,11 @@ inform_node_info(PCP_CONNECTION *frontend,char *buf) ereport(ERROR, (errmsg("informing node info failed"), errdetail("invalid node ID"))); - + ereport(DEBUG2, (errmsg("PCP: informing node info"), errdetail("retrieved node information from shared memory"))); - + snprintf(port_str, sizeof(port_str), "%d", bi->backend_port); snprintf(status, sizeof(status), "%d", bi->backend_status); snprintf(weight_str, sizeof(weight_str), "%f", bi->backend_weight); @@ -853,47 +863,47 @@ inform_node_info(PCP_CONNECTION *frontend,char *buf) snprintf(standby_delay_str, sizeof(standby_delay_str), UINT64_FORMAT, bi->standby_delay); snprintf(status_changed_time_str, sizeof(status_changed_time_str), UINT64_FORMAT, bi->status_changed_time); - + pcp_write(frontend, "i", 1); wsize = htonl(sizeof(code) + - strlen(bi->backend_hostname)+1 + - strlen(port_str)+1 + - strlen(status)+1 + - strlen(weight_str)+1 + - strlen(role_str)+1 + - strlen(standby_delay_str)+1 + - strlen(status_changed_time_str)+1 + + strlen(bi->backend_hostname) + 1 + + strlen(port_str) + 1 + + strlen(status) + 1 + + strlen(weight_str) + 1 + + strlen(role_str) + 1 + + strlen(standby_delay_str) + 1 + + strlen(status_changed_time_str) + 1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname)+1); - pcp_write(frontend, port_str, strlen(port_str)+1); - pcp_write(frontend, status, strlen(status)+1); - pcp_write(frontend, weight_str, strlen(weight_str)+1); - pcp_write(frontend, role_str, strlen(role_str)+1); - pcp_write(frontend, standby_delay_str, strlen(standby_delay_str)+1); - pcp_write(frontend, status_changed_time_str, strlen(status_changed_time_str)+1); + pcp_write(frontend, bi->backend_hostname, strlen(bi->backend_hostname) + 1); + pcp_write(frontend, port_str, strlen(port_str) + 1); + pcp_write(frontend, status, strlen(status) + 1); + pcp_write(frontend, weight_str, strlen(weight_str) + 1); + pcp_write(frontend, role_str, strlen(role_str) + 1); + pcp_write(frontend, standby_delay_str, strlen(standby_delay_str) + 1); + pcp_write(frontend, status_changed_time_str, strlen(status_changed_time_str) + 1); do_pcp_flush(frontend); } static void -inform_node_count(PCP_CONNECTION *frontend) +inform_node_count(PCP_CONNECTION * frontend) { - int wsize; - char mesg[16]; - char code[] = "CommandComplete"; - int node_count = pool_get_node_count(); + int wsize; + char mesg[16]; + char code[] = "CommandComplete"; + int node_count = pool_get_node_count(); snprintf(mesg, sizeof(mesg), "%d", node_count); pcp_write(frontend, "l", 1); wsize = htonl(sizeof(code) + - strlen(mesg)+1 + + strlen(mesg) + 1 + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, mesg, strlen(mesg)+1); + pcp_write(frontend, mesg, strlen(mesg) + 1); do_pcp_flush(frontend); ereport(DEBUG1, @@ -902,12 +912,12 @@ inform_node_count(PCP_CONNECTION *frontend) } static void -process_detach_node(PCP_CONNECTION *frontend,char *buf, char tos) +process_detach_node(PCP_CONNECTION * frontend, char *buf, char tos) { - int node_id; - int wsize; - char code[] = "CommandComplete"; - bool gracefully; + int node_id; + int wsize; + char code[] = "CommandComplete"; + bool gracefully; if (tos == 'D') gracefully = false; @@ -929,18 +939,18 @@ process_detach_node(PCP_CONNECTION *frontend,char *buf, char tos) } static void -process_attach_node(PCP_CONNECTION *frontend,char *buf) +process_attach_node(PCP_CONNECTION * frontend, char *buf) { - int node_id; - int wsize; - char code[] = "CommandComplete"; + int node_id; + int wsize; + char code[] = "CommandComplete"; node_id = atoi(buf); ereport(DEBUG1, (errmsg("PCP: processing attach node"), errdetail("attaching Node ID %d", node_id))); - send_failback_request(node_id,true, REQ_DETAIL_CONFIRMED); + send_failback_request(node_id, true, REQ_DETAIL_CONFIRMED); pcp_write(frontend, "c", 1); wsize = htonl(sizeof(code) + sizeof(int)); @@ -951,15 +961,15 @@ process_attach_node(PCP_CONNECTION *frontend,char *buf) static void -process_recovery_request(PCP_CONNECTION *frontend,char *buf) +process_recovery_request(PCP_CONNECTION * frontend, char *buf) { - int wsize; - char code[] = "CommandComplete"; - int node_id = atoi(buf); + int wsize; + char code[] = "CommandComplete"; + int node_id = atoi(buf); - if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) ) + if ((node_id < 0) || (node_id >= pool_config->backend_desc->num_backends)) ereport(ERROR, - (errmsg("process recovery request failed"), + (errmsg("process recovery request failed"), errdetail("node id %d is not valid", node_id))); if ((!REPLICATION && @@ -971,22 +981,22 @@ process_recovery_request(PCP_CONNECTION *frontend,char *buf) { if (MASTER_SLAVE && pool_config->master_slave_sub_mode == STREAM_MODE) ereport(ERROR, - (errmsg("process recovery request failed"), + (errmsg("process recovery request failed"), errdetail("primary server cannot be recovered by online recovery."))); else ereport(ERROR, - (errmsg("process recovery request failed"), + (errmsg("process recovery request failed"), errdetail("recovery request is only allowed in replication and streaming replication modes."))); } else { if (pcp_mark_recovery_in_progress() == false) ereport(FATAL, - (errmsg("process recovery request failed"), + (errmsg("process recovery request failed"), errdetail("pgpool-II is already processing another recovery request."))); ereport(DEBUG1, - (errmsg("PCP: processing recovery request"), + (errmsg("PCP: processing recovery request"), errdetail("start online recovery"))); PG_TRY(); @@ -1005,24 +1015,26 @@ process_recovery_request(PCP_CONNECTION *frontend,char *buf) finish_recovery(); pcp_mark_recovery_finished(); PG_RE_THROW(); - - }PG_END_TRY(); + + } PG_END_TRY(); } do_pcp_flush(frontend); } static void -process_status_request(PCP_CONNECTION *frontend) +process_status_request(PCP_CONNECTION * frontend) { - int nrows = 0; - int i; + int nrows = 0; + int i; POOL_REPORT_CONFIG *status = get_config(&nrows); - int len = 0; + int len = 0; + /* First, send array size of connection_info */ - char arr_code[] = "ArraySize"; - char code[] = "ProcessConfig"; + char arr_code[] = "ArraySize"; + char code[] = "ProcessConfig"; + /* Finally, indicate that all data is sent */ - char fin_code[] = "CommandComplete"; + char fin_code[] = "CommandComplete"; pcp_write(frontend, "b", 1); len = htonl(sizeof(arr_code) + sizeof(int) + sizeof(int)); @@ -1041,13 +1053,13 @@ process_status_request(PCP_CONNECTION *frontend) + strlen(status[i].name) + 1 + strlen(status[i].value) + 1 + strlen(status[i].desc) + 1 - ); + ); pcp_write(frontend, &len, sizeof(int)); pcp_write(frontend, code, sizeof(code)); - pcp_write(frontend, status[i].name, strlen(status[i].name)+1); - pcp_write(frontend, status[i].value, strlen(status[i].value)+1); - pcp_write(frontend, status[i].desc, strlen(status[i].desc)+1); + pcp_write(frontend, status[i].name, strlen(status[i].name) + 1); + pcp_write(frontend, status[i].value, strlen(status[i].value) + 1); + pcp_write(frontend, status[i].desc, strlen(status[i].desc) + 1); } pcp_write(frontend, "b", 1); @@ -1063,20 +1075,20 @@ process_status_request(PCP_CONNECTION *frontend) } static void -process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos) +process_promote_node(PCP_CONNECTION * frontend, char *buf, char tos) { - int node_id; - int wsize; - char code[] = "CommandComplete"; - bool gracefully; + int node_id; + int wsize; + char code[] = "CommandComplete"; + bool gracefully; if (tos == 'J') gracefully = false; else gracefully = true; - + node_id = atoi(buf); - if ( (node_id < 0) || (node_id >= pool_config->backend_desc->num_backends) ) + if ((node_id < 0) || (node_id >= pool_config->backend_desc->num_backends)) ereport(ERROR, (errmsg("could not process recovery request"), errdetail("node id %d is not valid", node_id))); @@ -1084,9 +1096,9 @@ process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos) if (!MASTER_SLAVE || pool_config->master_slave_sub_mode != STREAM_MODE) { ereport(FATAL, - (errmsg("invalid pgpool mode for process recovery request"), + (errmsg("invalid pgpool mode for process recovery request"), errdetail("not in streaming replication mode, can't promote node id %d", node_id))); - + } if (node_id == REAL_PRIMARY_NODE_ID) @@ -1094,7 +1106,7 @@ process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos) ereport(FATAL, (errmsg("invalid pgpool mode for process recovery request"), errdetail("specified node is already primary node, can't promote node id %d", node_id))); - + } ereport(DEBUG1, (errmsg("PCP: processing promote node"), @@ -1109,10 +1121,10 @@ process_promote_node(PCP_CONNECTION *frontend, char *buf, char tos) } static void -process_authentication(PCP_CONNECTION *frontend, char *buf, char* salt, int *random_salt) +process_authentication(PCP_CONNECTION * frontend, char *buf, char *salt, int *random_salt) { - int wsize; - int authenticated; + int wsize; + int authenticated; if (*random_salt) { @@ -1121,14 +1133,15 @@ process_authentication(PCP_CONNECTION *frontend, char *buf, char* salt, int *ran if (!*random_salt || !authenticated) { ereport(FATAL, - (errmsg("authentication failed"), + (errmsg("authentication failed"), errdetail("username and/or password does not match"))); *random_salt = 0; } else { - char code[] = "AuthenticationOK"; + char code[] = "AuthenticationOK"; + pcp_write(frontend, "r", 1); wsize = htonl(sizeof(code) + sizeof(int)); pcp_write(frontend, &wsize, sizeof(int)); @@ -1137,15 +1150,16 @@ process_authentication(PCP_CONNECTION *frontend, char *buf, char* salt, int *ran *random_salt = 0; ereport(DEBUG1, - (errmsg("PCP: processing authentication request"), + (errmsg("PCP: processing authentication request"), errdetail("authentication OK"))); } } static void -send_md5salt(PCP_CONNECTION *frontend, char* salt) +send_md5salt(PCP_CONNECTION * frontend, char *salt) { - int wsize; + int wsize; + ereport(DEBUG1, (errmsg("PCP: sending md5 salt to client"))); @@ -1159,11 +1173,12 @@ send_md5salt(PCP_CONNECTION *frontend, char* salt) } static void -process_shutown_request(PCP_CONNECTION *frontend, char mode) +process_shutown_request(PCP_CONNECTION * frontend, char mode) { - char code[] = "CommandComplete"; - pid_t ppid = getppid(); - int sig,len; + char code[] = "CommandComplete"; + pid_t ppid = getppid(); + int sig, + len; if (mode == 's') { @@ -1203,38 +1218,40 @@ process_shutown_request(PCP_CONNECTION *frontend, char mode) } static void -process_set_configration_parameter(PCP_CONNECTION *frontend,char *buf, int len) +process_set_configration_parameter(PCP_CONNECTION * frontend, char *buf, int len) { - char* param_name; - char* param_value; - int wsize; - char code[] = "CommandComplete"; + char *param_name; + char *param_value; + int wsize; + char code[] = "CommandComplete"; param_name = buf; - if(param_name == NULL) + if (param_name == NULL) ereport(ERROR, (errmsg("PCP: set configuration parameter failed"), errdetail("invalid pcp packet received from client"))); param_value = (char *) memchr(buf, '\0', len); - if(param_value == NULL) + if (param_value == NULL) ereport(ERROR, - (errmsg("set configuration parameter failed"), + (errmsg("set configuration parameter failed"), errdetail("invalid pcp packet received from client"))); - param_value +=1; + param_value += 1; ereport(LOG, - (errmsg("set configuration parameter, \"%s TO %s\"",param_name,param_value))); - - if(strcasecmp(param_name, "client_min_messages") == 0) + (errmsg("set configuration parameter, \"%s TO %s\"", param_name, param_value))); + + if (strcasecmp(param_name, "client_min_messages") == 0) { - const char *ordered_valid_values[] = {"debug5","debug4","debug3","debug2","debug1","log","commerror","info","notice","warning","error",NULL}; - bool found = false; - int i; - for(i=0; ; i++) + const char *ordered_valid_values[] = {"debug5", "debug4", "debug3", "debug2", "debug1", "log", "commerror", "info", "notice", "warning", "error", NULL}; + bool found = false; + int i; + + for (i = 0;; i++) { - char* valid_val = (char*)ordered_valid_values[i]; - if(!valid_val) + char *valid_val = (char *) ordered_valid_values[i]; + + if (!valid_val) break; if (!strcasecmp(param_value, valid_val)) @@ -1242,19 +1259,19 @@ process_set_configration_parameter(PCP_CONNECTION *frontend,char *buf, int len) found = true; pool_config->client_min_messages = i + 10; ereport(DEBUG1, - (errmsg("PCP setting parameter \"%s\" to \"%s\"",param_name,param_value))); + (errmsg("PCP setting parameter \"%s\" to \"%s\"", param_name, param_value))); break; } } if (!found) ereport(ERROR, - (errmsg("PCP: set configuration parameter failed"), - errdetail("invalid value \"%s\" for parameter \"%s\"",param_value,param_name))); + (errmsg("PCP: set configuration parameter failed"), + errdetail("invalid value \"%s\" for parameter \"%s\"", param_value, param_name))); } else ereport(ERROR, - (errmsg("PCP: set configuration parameter failed"), - errdetail("invalid parameter \"%s\"",param_name))); + (errmsg("PCP: set configuration parameter failed"), + errdetail("invalid parameter \"%s\"", param_name))); pcp_write(frontend, "a", 1); wsize = htonl(sizeof(code) + sizeof(int)); @@ -1262,33 +1279,36 @@ process_set_configration_parameter(PCP_CONNECTION *frontend,char *buf, int len) pcp_write(frontend, code, sizeof(code)); do_pcp_flush(frontend); } + /* * Wrapper around pcp_flush which throws FATAL error when pcp_flush fails */ static void -do_pcp_flush(PCP_CONNECTION *frontend) +do_pcp_flush(PCP_CONNECTION * frontend) { if (pcp_flush(frontend) < 0) ereport(FATAL, - (errmsg("failed to flush data to client"), - errdetail("pcp_flush failed with error : \"%s\"",strerror(errno)))); + (errmsg("failed to flush data to client"), + errdetail("pcp_flush failed with error : \"%s\"", strerror(errno)))); } /* * Wrapper around pcp_read which throws FATAL error when read fails */ static void -do_pcp_read(PCP_CONNECTION *pc, void *buf, int len) +do_pcp_read(PCP_CONNECTION * pc, void *buf, int len) { - if (pcp_read(pc,buf,len)) + if (pcp_read(pc, buf, len)) ereport(FATAL, (errmsg("unable to read from client"), - errdetail("pcp_read failed with error : \"%s\"",strerror(errno)))); + errdetail("pcp_read failed with error : \"%s\"", strerror(errno)))); } -int send_to_pcp_frontend(char* data, int len, bool flush) +int +send_to_pcp_frontend(char *data, int len, bool flush) { - int ret; + int ret; + if (processType != PT_PCP_WORKER || pcp_frontend == NULL) return -1; ret = pcp_write(pcp_frontend, data, len); @@ -1297,14 +1317,16 @@ int send_to_pcp_frontend(char* data, int len, bool flush) return ret; } -int pcp_frontend_exists(void) +int +pcp_frontend_exists(void) { if (processType != PT_PCP_WORKER || pcp_frontend == NULL) return -1; return 0; } -static void pcp_worker_will_go_down(int code, Datum arg) +static void +pcp_worker_will_go_down(int code, Datum arg) { if (processType != PT_PCP_WORKER) { @@ -1313,9 +1335,9 @@ static void pcp_worker_will_go_down(int code, Datum arg) (errmsg("pcp_worker_will_go_down called from invalid process"))); return; } - if(pcp_frontend) + if (pcp_frontend) pcp_close(pcp_frontend); processState = EXITING; POOL_SETMASK(&UnBlockSig); - + } diff --git a/src/pcp_con/recovery.c b/src/pcp_con/recovery.c index 0d30e4a99..4c44fc0b2 100644 --- a/src/pcp_con/recovery.c +++ b/src/pcp_con/recovery.c @@ -41,10 +41,10 @@ #define SECOND_STAGE 1 static void exec_checkpoint(PGconn *conn); -static void exec_recovery(PGconn *conn, BackendInfo *master_backend, BackendInfo *recovery_backend, char stage, int recovery_node); -static void exec_remote_start(PGconn *conn, BackendInfo *backend); -static PGconn *connect_backend_libpq(BackendInfo *backend); -static void check_postmaster_started(BackendInfo *backend); +static void exec_recovery(PGconn *conn, BackendInfo * master_backend, BackendInfo * recovery_backend, char stage, int recovery_node); +static void exec_remote_start(PGconn *conn, BackendInfo * backend); +static PGconn *connect_backend_libpq(BackendInfo * backend); +static void check_postmaster_started(BackendInfo * backend); static char recovery_command[1024]; @@ -55,19 +55,21 @@ extern volatile sig_atomic_t pcp_worker_wakeup_request; * "recovery_node" is the node to be recovered. * Master or primary node is chosen in this function. */ -void start_recovery(int recovery_node) +void +start_recovery(int recovery_node) { - int node_id; + int node_id; BackendInfo *backend; BackendInfo *recovery_backend; - PGconn *conn; - int failback_wait_count; -#define FAILBACK_WAIT_MAX_RETRY 5 /* 5 seconds should be enough for failback operation */ + PGconn *conn; + int failback_wait_count; +#define FAILBACK_WAIT_MAX_RETRY 5 /* 5 seconds should be enough for failback + * operation */ ereport(LOG, - (errmsg("starting recovering node %d", recovery_node))); + (errmsg("starting recovering node %d", recovery_node))); - if ( (recovery_node < 0) || (recovery_node >= pool_config->backend_desc->num_backends) ) + if ((recovery_node < 0) || (recovery_node >= pool_config->backend_desc->num_backends)) ereport(ERROR, (errmsg("node recovery failed, node id: %d is not valid", recovery_node))); @@ -98,18 +100,18 @@ void start_recovery(int recovery_node) { exec_checkpoint(conn); ereport(LOG, - (errmsg("node recovery, CHECKPOINT in the 1st stage done"))); + (errmsg("node recovery, CHECKPOINT in the 1st stage done"))); } exec_recovery(conn, backend, recovery_backend, FIRST_STAGE, recovery_node); ereport(LOG, - (errmsg("node recovery, 1st stage is done"))); + (errmsg("node recovery, 1st stage is done"))); if (REPLICATION) { ereport(LOG, - (errmsg("node recovery, starting 2nd stage"))); + (errmsg("node recovery, starting 2nd stage"))); /* 2nd stage */ *InRecovery = RECOVERY_ONLINE; @@ -126,12 +128,12 @@ void start_recovery(int recovery_node) (errmsg("node recovery failed, waiting connection closed in the other pgpools timeout"))); ereport(LOG, - (errmsg("node recovery, all connections from clients have been closed"))); + (errmsg("node recovery, all connections from clients have been closed"))); exec_checkpoint(conn); ereport(LOG, - (errmsg("node recovery"), + (errmsg("node recovery"), errdetail("CHECKPOINT in the 2nd stage done"))); exec_recovery(conn, backend, recovery_backend, SECOND_STAGE, recovery_node); @@ -142,31 +144,32 @@ void start_recovery(int recovery_node) check_postmaster_started(recovery_backend); ereport(LOG, - (errmsg("node recovery, node: %d restarted", recovery_node))); + (errmsg("node recovery, node: %d restarted", recovery_node))); /* - * reset failover completion flag. this is necessary since - * previous failover/failback will set the flag to 1. + * reset failover completion flag. this is necessary since previous + * failover/failback will set the flag to 1. */ pcp_worker_wakeup_request = 0; /* send failback request to pgpool parent */ - send_failback_request(recovery_node,false, REQ_DETAIL_CONFIRMED); + send_failback_request(recovery_node, false, REQ_DETAIL_CONFIRMED); /* wait for failback */ failback_wait_count = 0; while (!pcp_worker_wakeup_request) { struct timeval t = {1, 0}; + /* polling SIGUSR2 signal every 1 sec */ select(0, NULL, NULL, NULL, &t); failback_wait_count++; if (failback_wait_count >= FAILBACK_WAIT_MAX_RETRY) { ereport(LOG, - (errmsg("node recovery"), - errdetail("waiting for wake up request is timeout(%d seconds)", - FAILBACK_WAIT_MAX_RETRY))); + (errmsg("node recovery"), + errdetail("waiting for wake up request is timeout(%d seconds)", + FAILBACK_WAIT_MAX_RETRY))); break; } @@ -189,7 +192,8 @@ void start_recovery(int recovery_node) /* * Notice all children finishing recovery. */ -void finish_recovery(void) +void +finish_recovery(void) { /* announce end recovery */ if (pool_config->use_watchdog && *InRecovery != RECOVERY_INIT) @@ -204,30 +208,33 @@ void finish_recovery(void) /* * Execute CHECKPOINT */ -static void exec_checkpoint(PGconn *conn) +static void +exec_checkpoint(PGconn *conn) { - PGresult *result; + PGresult *result; + ereport(DEBUG1, - (errmsg("recovery execute checkpoint, start checkpoint"))); + (errmsg("recovery execute checkpoint, start checkpoint"))); result = PQexec(conn, "CHECKPOINT"); - if(PQresultStatus(result) != PGRES_COMMAND_OK) + if (PQresultStatus(result) != PGRES_COMMAND_OK) ereport(ERROR, (errmsg("executing recovery, execute CHECKPOINT failed"))); PQclear(result); ereport(DEBUG1, - (errmsg("recovery execute checkpoint, finish checkpoint"))); + (errmsg("recovery execute checkpoint, finish checkpoint"))); } /* * Call pgpool_recovery() function. */ -static void exec_recovery(PGconn *conn, BackendInfo *master_backend, BackendInfo *recovery_backend, char stage, int recovery_node) +static void +exec_recovery(PGconn *conn, BackendInfo * master_backend, BackendInfo * recovery_backend, char stage, int recovery_node) { - PGresult *result; - char *hostname; - char *script; + PGresult *result; + char *hostname; + char *script; if (strlen(recovery_backend->backend_hostname) == 0 || *(recovery_backend->backend_hostname) == '/') hostname = "localhost"; @@ -257,44 +264,45 @@ static void exec_recovery(PGconn *conn, BackendInfo *master_backend, BackendInfo ); ereport(LOG, - (errmsg("executing recovery"), + (errmsg("executing recovery"), errdetail("starting recovery command: \"%s\"", recovery_command))); ereport(LOG, - (errmsg("executing recovery"), + (errmsg("executing recovery"), errdetail("disabling statement_timeout"))); result = PQexec(conn, "SET statement_timeout To 0"); - if(PQresultStatus(result) != PGRES_COMMAND_OK) + if (PQresultStatus(result) != PGRES_COMMAND_OK) ereport(ERROR, (errmsg("executing recovery, SET STATEMENT_TIMEOUT failed at \"%s\"", (stage == FIRST_STAGE) ? "1st stage" : "2nd stage"))); - + PQclear(result); ereport(DEBUG1, - (errmsg("executing recovery, start recovery"))); + (errmsg("executing recovery, start recovery"))); result = PQexec(conn, recovery_command); - if(PQresultStatus(result) != PGRES_TUPLES_OK) + if (PQresultStatus(result) != PGRES_TUPLES_OK) ereport(ERROR, (errmsg("executing recovery, execution of command failed at \"%s\"", (stage == FIRST_STAGE) ? "1st stage" : "2nd stage"), - errdetail("command:\"%s\"",script))); - + errdetail("command:\"%s\"", script))); + PQclear(result); ereport(DEBUG1, - (errmsg("executing recovery, finish recovery"))); + (errmsg("executing recovery, finish recovery"))); } /* * Call pgpool_remote_start() function. */ -static void exec_remote_start(PGconn *conn, BackendInfo *backend) +static void +exec_remote_start(PGconn *conn, BackendInfo * backend) { - PGresult *result; - char *hostname; + PGresult *result; + char *hostname; if (strlen(backend->backend_hostname) == 0 || *(backend->backend_hostname) == '/') hostname = "localhost"; @@ -307,47 +315,49 @@ static void exec_remote_start(PGconn *conn, BackendInfo *backend) backend->backend_data_directory); ereport(DEBUG1, - (errmsg("executing remote start"), + (errmsg("executing remote start"), errdetail("start pgpool_remote_start"))); result = PQexec(conn, recovery_command); - if(PQresultStatus(result) != PGRES_TUPLES_OK) + if (PQresultStatus(result) != PGRES_TUPLES_OK) ereport(ERROR, - (errmsg("executing remote start failed with error: \"%s\"",PQresultErrorMessage(result)))); + (errmsg("executing remote start failed with error: \"%s\"", PQresultErrorMessage(result)))); PQclear(result); ereport(DEBUG1, - (errmsg("executing remote start"), + (errmsg("executing remote start"), errdetail("finish pgpool_remote_start"))); } /* * Check postmaster is started. */ -static void check_postmaster_started(BackendInfo *backend) +static void +check_postmaster_started(BackendInfo * backend) { - int i = 0; - char port_str[16]; - PGconn *conn; - char *dbname; - char *password = get_pgpool_config_user_password(pool_config->recovery_user, - pool_config->recovery_password); + int i = 0; + char port_str[16]; + PGconn *conn; + char *dbname; + char *password = get_pgpool_config_user_password(pool_config->recovery_user, + pool_config->recovery_password); - snprintf(port_str, sizeof(port_str),"%d", backend->backend_port); + snprintf(port_str, sizeof(port_str), "%d", backend->backend_port); /* * First we try with "postgres" database. */ dbname = "postgres"; - do { + do + { ConnStatusType r; ereport(LOG, - (errmsg("checking if postmaster is started"), - errdetail("trying to connect to postmaster on hostname:%s database:%s user:%s (retry %d times)", - backend->backend_hostname, dbname, pool_config->recovery_user, i))); + (errmsg("checking if postmaster is started"), + errdetail("trying to connect to postmaster on hostname:%s database:%s user:%s (retry %d times)", + backend->backend_hostname, dbname, pool_config->recovery_user, i))); conn = PQsetdbLogin(backend->backend_hostname, port_str, @@ -355,7 +365,7 @@ static void check_postmaster_started(BackendInfo *backend) NULL, dbname, pool_config->recovery_user, - password?password:NULL); + password ? password : NULL); r = PQstatus(conn); PQfinish(conn); @@ -363,15 +373,15 @@ static void check_postmaster_started(BackendInfo *backend) { if (password) pfree(password); - return; + return; } ereport(LOG, - (errmsg("checking if postmaster is started"), - errdetail("failed to connect to postmaster on hostname:%s database:%s user:%s", - backend->backend_hostname, dbname, pool_config->recovery_user))); - + (errmsg("checking if postmaster is started"), + errdetail("failed to connect to postmaster on hostname:%s database:%s user:%s", + backend->backend_hostname, dbname, pool_config->recovery_user))); + sleep(3); - } while (i++ < 3); /* XXX Hard coded retry (9 seconds) */ + } while (i++ < 3); /* XXX Hard coded retry (9 seconds) */ /* * Retry with "template1" database. @@ -379,13 +389,14 @@ static void check_postmaster_started(BackendInfo *backend) dbname = "template1"; i = 0; - do { + do + { ConnStatusType r; ereport(LOG, - (errmsg("checking if postmaster is started"), - errdetail("trying to connect to postmaster on hostname:%s database:%s user:%s (retry %d times)", - backend->backend_hostname, dbname, pool_config->recovery_user, i))); + (errmsg("checking if postmaster is started"), + errdetail("trying to connect to postmaster on hostname:%s database:%s user:%s (retry %d times)", + backend->backend_hostname, dbname, pool_config->recovery_user, i))); conn = PQsetdbLogin(backend->backend_hostname, port_str, @@ -393,7 +404,7 @@ static void check_postmaster_started(BackendInfo *backend) NULL, dbname, pool_config->recovery_user, - password?password:NULL); + password ? password : NULL); r = PQstatus(conn); PQfinish(conn); @@ -405,7 +416,7 @@ static void check_postmaster_started(BackendInfo *backend) } ereport(LOG, - (errmsg("checking if postmaster is started"), + (errmsg("checking if postmaster is started"), errdetail("failed to connect to postmaster on hostname:%s database:%s user:%s", backend->backend_hostname, dbname, pool_config->recovery_user))); @@ -417,17 +428,18 @@ static void check_postmaster_started(BackendInfo *backend) pfree(password); ereport(ERROR, - (errmsg("recovery is checking if postmaster is started"), + (errmsg("recovery is checking if postmaster is started"), errdetail("postmaster on hostname:\"%s\" database:\"%s\" user:\"%s\" failed to start in %d second", backend->backend_hostname, dbname, pool_config->recovery_user, pool_config->recovery_timeout))); } -static PGconn *connect_backend_libpq(BackendInfo *backend) +static PGconn * +connect_backend_libpq(BackendInfo * backend) { - char port_str[16]; - PGconn *conn; - char *password = get_pgpool_config_user_password(pool_config->recovery_user, - pool_config->recovery_password); + char port_str[16]; + PGconn *conn; + char *password = get_pgpool_config_user_password(pool_config->recovery_user, + pool_config->recovery_password); snprintf(port_str, sizeof(port_str), "%d", backend->backend_port); @@ -437,7 +449,7 @@ static PGconn *connect_backend_libpq(BackendInfo *backend) NULL, "template1", pool_config->recovery_user, - password?password:""); + password ? password : ""); if (password) pfree(password); @@ -453,11 +465,13 @@ static PGconn *connect_backend_libpq(BackendInfo *backend) /* * Wait all connections are closed. */ -int wait_connection_closed(void) +int +wait_connection_closed(void) { - int i = 0; + int i = 0; - do { + do + { if (Req_info->conn_counter == 0) return 0; diff --git a/src/protocol/CommandComplete.c b/src/protocol/CommandComplete.c index 9e8c265e2..820e0f3dd 100644 --- a/src/protocol/CommandComplete.c +++ b/src/protocol/CommandComplete.c @@ -1,8 +1,8 @@ /* -*-pgsql-c-*- */ /* * $Header$ - * - * pgpool: a language independent connection pool server for PostgreSQL + * + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2018 PgPool Global Development Group @@ -39,19 +39,22 @@ #include "utils/memutils.h" #include "utils/pool_stream.h" -static int extract_ntuples(char *message); -static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *packet, int packetlen, bool command_complete); -static int foward_command_complete(POOL_CONNECTION *frontend, char *packet, int packetlen); -static int foward_empty_query(POOL_CONNECTION *frontend, char *packet, int packetlen); -static int foward_packet_to_frontend(POOL_CONNECTION *frontend, char kind, char *packet, int packetlen); +static int extract_ntuples(char *message); +static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *packet, int packetlen, bool command_complete); +static int foward_command_complete(POOL_CONNECTION * frontend, char *packet, int packetlen); +static int foward_empty_query(POOL_CONNECTION * frontend, char *packet, int packetlen); +static int foward_packet_to_frontend(POOL_CONNECTION * frontend, char kind, char *packet, int packetlen); -POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, bool command_complete) +POOL_STATUS +CommandComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, bool command_complete) { - int len, len1; - char *p, *p1; - int i; + int len, + len1; + char *p, + *p1; + int i; POOL_SESSION_CONTEXT *session_context; - POOL_CONNECTION *con; + POOL_CONNECTION *con; p1 = NULL; len1 = 0; @@ -67,12 +70,12 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* * If operated in streaming replication mode and doing an extended query, - * read backend message according to the query context. - * Also we set the transaction state at this point. + * read backend message according to the query context. Also we set the + * transaction state at this point. */ if (SL_MODE && pool_is_doing_extended_query_message()) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -94,7 +97,7 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (session_context->query_context && session_context->query_context->parse_tree && is_start_transaction_query(session_context->query_context->parse_tree)) - TSTATE(backend, i) ='T'; /* we are inside a transaction */ + TSTATE(backend, i) = 'T'; /* we are inside a transaction */ { ereport(DEBUG1, (errmsg("processing command complete"), @@ -103,6 +106,7 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac } } } + /* * Otherwise just read from master node. */ @@ -132,7 +136,7 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac */ if (SL_MODE && pool_is_doing_extended_query_message()) { - int status; + int status; if (p1 == NULL) { @@ -168,9 +172,9 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac */ if (SL_MODE && pool_is_doing_extended_query_message()) { - char *query; - Node *node; - char state; + char *query; + Node *node; + char state; if (session_context->query_context == NULL) { @@ -194,7 +198,7 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* * If we are in streaming replication mode and we are doing extended * query, reset query in progress flag and prevoius pending message. - */ + */ if (SL_MODE && pool_is_doing_extended_query_message()) { pool_at_command_success(frontend, backend); @@ -208,10 +212,11 @@ POOL_STATUS CommandComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* * Handle misc process which is neccessary when query context exists. */ -void handle_query_context(POOL_CONNECTION_POOL *backend) +void +handle_query_context(POOL_CONNECTION_POOL * backend) { POOL_SESSION_CONTEXT *session_context; - Node *node; + Node *node; /* Get session context */ session_context = pool_get_session_context(false); @@ -228,9 +233,9 @@ void handle_query_context(POOL_CONNECTION_POOL *backend) } else if (IsA(node, DeallocateStmt)) { - char *name; - - name = ((DeallocateStmt *)node)->name; + char *name; + + name = ((DeallocateStmt *) node)->name; if (name == NULL) { pool_remove_sent_messages('Q'); @@ -244,7 +249,7 @@ void handle_query_context(POOL_CONNECTION_POOL *backend) } else if (IsA(node, DiscardStmt)) { - DiscardStmt *stmt = (DiscardStmt *)node; + DiscardStmt *stmt = (DiscardStmt *) node; if (stmt->target == DISCARD_PLANS) { @@ -256,15 +261,15 @@ void handle_query_context(POOL_CONNECTION_POOL *backend) pool_clear_sent_message_list(); } } + /* - * JDBC driver sends "BEGIN" query internally if - * setAutoCommit(false). But it does not send Sync message - * after "BEGIN" query. In extended query protocol, - * PostgreSQL returns ReadyForQuery when a client sends Sync - * message. Problem is, pgpool can't know the transaction - * state without receiving ReadyForQuery. So we remember that - * we need to send Sync message internally afterward, whenever - * we receive BEGIN in extended protocol. + * JDBC driver sends "BEGIN" query internally if setAutoCommit(false). + * But it does not send Sync message after "BEGIN" query. In extended + * query protocol, PostgreSQL returns ReadyForQuery when a client sends + * Sync message. Problem is, pgpool can't know the transaction state + * without receiving ReadyForQuery. So we remember that we need to send + * Sync message internally afterward, whenever we receive BEGIN in + * extended protocol. */ else if (IsA(node, TransactionStmt)) { @@ -272,7 +277,7 @@ void handle_query_context(POOL_CONNECTION_POOL *backend) if (stmt->kind == TRANS_STMT_BEGIN || stmt->kind == TRANS_STMT_START) { - int i; + int i; for (i = 0; i < NUM_BACKENDS; i++) { @@ -294,16 +299,18 @@ void handle_query_context(POOL_CONNECTION_POOL *backend) /* * Extract the number of tuples from CommandComplete message */ -static int extract_ntuples(char *message) +static int +extract_ntuples(char *message) { - char *rows; + char *rows; if ((rows = strstr(message, "UPDATE")) || (rows = strstr(message, "DELETE"))) - rows +=7; + rows += 7; else if ((rows = strstr(message, "INSERT"))) { rows += 7; - while (*rows && *rows != ' ') rows++; + while (*rows && *rows != ' ') + rows++; } else return 0; @@ -314,14 +321,14 @@ static int extract_ntuples(char *message) /* * Handle mismatch tuples */ -static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *packet, int packetlen, bool command_complete) +static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *packet, int packetlen, bool command_complete) { POOL_SESSION_CONTEXT *session_context; - int rows; - int i; - int len; - char *p; + int rows; + int i; + int len; + char *p; /* Get session context */ session_context = pool_get_session_context(false); @@ -334,7 +341,7 @@ static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNEC session_context->ntuples[MASTER_NODE_ID] = rows; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!IS_MASTER_NODE_ID(i)) { @@ -356,12 +363,12 @@ static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNEC if (len != packetlen) { ereport(DEBUG1, - (errmsg("processing command complete"), - errdetail("length does not match between backends master(%d) %d th backend(%d)", - len, i, packetlen))); + (errmsg("processing command complete"), + errdetail("length does not match between backends master(%d) %d th backend(%d)", + len, i, packetlen))); } - int n = extract_ntuples(p); + int n = extract_ntuples(p); /* * Save number of affected tuples. @@ -381,27 +388,28 @@ static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNEC if (session_context->mismatch_ntuples) { - char msgbuf[128]; + char msgbuf[128]; + + String *msg = init_string("pgpool detected difference of the number of inserted, updated or deleted tuples. Possible last query was: \""); - String *msg = init_string("pgpool detected difference of the number of inserted, updated or deleted tuples. Possible last query was: \""); string_append_char(msg, query_string_buffer); string_append_char(msg, "\""); pool_send_error_message(frontend, MAJOR(backend), "XX001", msg->data, "", - "check data consistency between master and other db node", __FILE__, __LINE__); + "check data consistency between master and other db node", __FILE__, __LINE__); ereport(LOG, - (errmsg("%s", msg->data))); + (errmsg("%s", msg->data))); free_string(msg); msg = init_string("CommandComplete: Number of affected tuples are:"); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { snprintf(msgbuf, sizeof(msgbuf), " %d", session_context->ntuples[i]); string_append_char(msg, msgbuf); } ereport(LOG, - (errmsg("processing command complete"), + (errmsg("processing command complete"), errdetail("%s", msg->data))); free_string(msg); @@ -426,7 +434,8 @@ static POOL_STATUS handle_mismatch_tuples(POOL_CONNECTION *frontend, POOL_CONNEC /* * Forward Command complete packet to frontend */ -static int foward_command_complete(POOL_CONNECTION *frontend, char *packet, int packetlen) +static int +foward_command_complete(POOL_CONNECTION * frontend, char *packet, int packetlen) { return foward_packet_to_frontend(frontend, 'C', packet, packetlen); } @@ -434,7 +443,8 @@ static int foward_command_complete(POOL_CONNECTION *frontend, char *packet, int /* * Forward Empty query response to frontend */ -static int foward_empty_query(POOL_CONNECTION *frontend, char *packet, int packetlen) +static int +foward_empty_query(POOL_CONNECTION * frontend, char *packet, int packetlen) { return foward_packet_to_frontend(frontend, 'I', packet, packetlen); } @@ -442,14 +452,15 @@ static int foward_empty_query(POOL_CONNECTION *frontend, char *packet, int packe /* * Forward packet to frontend */ -static int foward_packet_to_frontend(POOL_CONNECTION *frontend, char kind, char *packet, int packetlen) +static int +foward_packet_to_frontend(POOL_CONNECTION * frontend, char kind, char *packet, int packetlen) { - int sendlen; + int sendlen; if (pool_write(frontend, &kind, 1) < 0) return -1; - sendlen = htonl(packetlen+4); + sendlen = htonl(packetlen + 4); if (pool_write(frontend, &sendlen, sizeof(sendlen)) < 0) return -1; diff --git a/src/protocol/child.c b/src/protocol/child.c index e0f114ce6..ef0ffda0e 100644 --- a/src/protocol/child.c +++ b/src/protocol/child.c @@ -59,35 +59,36 @@ #include "auth/pool_hba.h" -static StartupPacket *read_startup_packet(POOL_CONNECTION *cp); -static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend); +static StartupPacket *read_startup_packet(POOL_CONNECTION * cp); +static POOL_CONNECTION_POOL * connect_backend(StartupPacket *sp, POOL_CONNECTION * frontend); static RETSIGTYPE die(int sig); static RETSIGTYPE close_idle_connection(int sig); static RETSIGTYPE wakeup_handler(int sig); static RETSIGTYPE reload_config_handler(int sig); static RETSIGTYPE authentication_timeout(int sig); -static void send_params(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static void send_params(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); static void send_frontend_exits(void); static void connection_count_up(void); static void connection_count_down(void); -static bool connect_using_existing_connection(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - StartupPacket *sp); +static bool connect_using_existing_connection(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + StartupPacket *sp); static void check_restart_request(void); static void enable_authentication_timeout(void); static void disable_authentication_timeout(void); -static int wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr); +static int wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr); static void check_config_reload(void); static void get_backends_status(unsigned int *valid_backends, unsigned int *down_backends); static void validate_backend_connectivity(int front_end_fd); -static POOL_CONNECTION *get_connection(int front_end_fd, SockAddr *saddr); -static POOL_CONNECTION_POOL *get_backend_connection(POOL_CONNECTION *frontend); +static POOL_CONNECTION * get_connection(int front_end_fd, SockAddr *saddr); +static POOL_CONNECTION_POOL * get_backend_connection(POOL_CONNECTION * frontend); static StartupPacket *StartupPacketCopy(StartupPacket *sp); -static void print_process_status(char *remote_host,char* remote_port); -static bool backend_cleanup(POOL_CONNECTION* volatile *frontend, POOL_CONNECTION_POOL* volatile backend, bool frontend_invalid); -static void free_persisten_db_connection_memory(POOL_CONNECTION_POOL_SLOT *cp); -static int choose_db_node_id(char *str); +static void print_process_status(char *remote_host, char *remote_port); +static bool backend_cleanup(POOL_CONNECTION * volatile *frontend, POOL_CONNECTION_POOL * volatile backend, bool frontend_invalid); +static void free_persisten_db_connection_memory(POOL_CONNECTION_POOL_SLOT * cp); +static int choose_db_node_id(char *str); static void child_will_go_down(int code, Datum arg); + /* * non 0 means SIGTERM(smart shutdown) or SIGINT(fast shutdown) has arrived */ @@ -95,42 +96,44 @@ volatile sig_atomic_t exit_request = 0; static volatile sig_atomic_t alarm_enabled = false; -static int idle; /* non 0 means this child is in idle state */ -static int accepted = 0; +static int idle; /* non 0 means this child is in idle state */ +static int accepted = 0; -fd_set readmask; -int nsocks; -static int child_inet_fd = 0; -static int child_unix_fd = 0; +fd_set readmask; +int nsocks; +static int child_inet_fd = 0; +static int child_unix_fd = 0; -extern int myargc; +extern int myargc; extern char **myargv; -char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ +char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ volatile sig_atomic_t got_sighup = 0; -char remote_host[NI_MAXHOST]; /* client host */ -char remote_port[NI_MAXSERV]; /* client port */ -POOL_CONNECTION* volatile child_frontend = NULL; +char remote_host[NI_MAXHOST]; /* client host */ +char remote_port[NI_MAXSERV]; /* client port */ +POOL_CONNECTION *volatile child_frontend = NULL; #ifdef DEBUG -bool stop_now = false; +bool stop_now = false; #endif /* * child main loop */ -void do_child(int *fds) +void +do_child(int *fds) { sigjmp_buf local_sigjmp_buf; - POOL_CONNECTION_POOL* volatile backend = NULL; + POOL_CONNECTION_POOL *volatile backend = NULL; struct timeval now; struct timezone tz; struct timeval timeout; - static int connected = 0; /* non 0 if has been accepted connections from frontend */ - int connections_count = 0; /* used if child_max_connections > 0 */ - char psbuf[NI_MAXHOST + 128]; + static int connected = 0; /* non 0 if has been accepted connections from + * frontend */ + int connections_count = 0; /* used if child_max_connections > 0 */ + char psbuf[NI_MAXHOST + 128]; ereport(DEBUG2, (errmsg("I am Pgpool Child process with pid: %d", getpid()))); @@ -142,16 +145,16 @@ void do_child(int *fds) signal(SIGALRM, SIG_DFL); signal(SIGCHLD, SIG_DFL); signal(SIGTERM, die); - signal(SIGINT, die); + signal(SIGINT, die); signal(SIGQUIT, die); signal(SIGHUP, reload_config_handler); signal(SIGUSR1, close_idle_connection); signal(SIGUSR2, wakeup_handler); signal(SIGPIPE, SIG_IGN); - on_system_exit(child_will_go_down, (Datum)NULL); + on_system_exit(child_will_go_down, (Datum) NULL); - int *walk; + int *walk; #ifdef NONE_BLOCK /* set listen fds to none-blocking */ for (walk = fds; *walk != -1; walk++) @@ -163,16 +166,16 @@ void do_child(int *fds) nsocks = *walk; } nsocks++; - FD_ZERO(&readmask); + FD_ZERO(&readmask); for (walk = fds; *walk != -1; walk++) FD_SET(*walk, &readmask); /* Create per loop iteration memory context */ ProcessLoopContext = AllocSetContextCreate(TopMemoryContext, - "pgpool_child_main_loop", - ALLOCSET_DEFAULT_MINSIZE, - ALLOCSET_DEFAULT_INITSIZE, - ALLOCSET_DEFAULT_MAXSIZE); + "pgpool_child_main_loop", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); MemoryContextSwitchTo(TopMemoryContext); @@ -198,8 +201,8 @@ void do_child(int *fds) } /* - * Open pool_passwd in child process. This is necessary to avoid the - * file descriptor race condition reported in [pgpool-general: 1141]. + * Open pool_passwd in child process. This is necessary to avoid the file + * descriptor race condition reported in [pgpool-general: 1141]. */ if (strcmp("", pool_config->pool_passwd)) { @@ -209,57 +212,60 @@ void do_child(int *fds) if (sigsetjmp(local_sigjmp_buf, 1) != 0) { - POOL_PROCESS_CONTEXT *session; - bool frontend_invalid = getfrontendinvalid(); + POOL_PROCESS_CONTEXT *session; + bool frontend_invalid = getfrontendinvalid(); + disable_authentication_timeout(); /* Since not using PG_TRY, must reset error stack by hand */ - error_context_stack = NULL; + error_context_stack = NULL; /* - * Do not emit an error when EOF was encountered on frontend connection before the session - * was initialized. This is the normal behavior of psql to close and reconnect - * the connection when some authentication method is used + * Do not emit an error when EOF was encountered on frontend + * connection before the session was initialized. This is the normal + * behavior of psql to close and reconnect the connection when some + * authentication method is used */ - if(pool_get_session_context(true) || - !child_frontend || - child_frontend->socket_state != POOL_SOCKET_EOF) + if (pool_get_session_context(true) || + !child_frontend || + child_frontend->socket_state != POOL_SOCKET_EOF) EmitErrorReport(); - /* process the cleanup in ProcessLoopContext which will get reset - * during the next loop iteration - */ + /* + * process the cleanup in ProcessLoopContext which will get reset + * during the next loop iteration + */ MemoryContextSwitchTo(ProcessLoopContext); if (accepted) connection_count_down(); - - backend_cleanup(&child_frontend, backend, frontend_invalid); - session = pool_get_process_context(); + backend_cleanup(&child_frontend, backend, frontend_invalid); - if(session) - { - /* Destroy session context */ - pool_session_context_destroy(); + session = pool_get_process_context(); - /* Mark this connection pool is not connected from frontend */ - pool_coninfo_unset_frontend_connected(pool_get_process_context()->proc_id, pool_pool_index()); + if (session) + { + /* Destroy session context */ + pool_session_context_destroy(); + + /* Mark this connection pool is not connected from frontend */ + pool_coninfo_unset_frontend_connected(pool_get_process_context()->proc_id, pool_pool_index()); - /* increment queries counter if necessary */ - if ( pool_config->child_max_connections > 0 ) - connections_count++; + /* increment queries counter if necessary */ + if (pool_config->child_max_connections > 0) + connections_count++; - /* check if maximum connections count for this child reached */ - if ( ( pool_config->child_max_connections > 0 ) && - ( connections_count >= pool_config->child_max_connections ) ) - { - ereport(LOG, - (errmsg("child exiting, %d connections reached", pool_config->child_max_connections))); + /* check if maximum connections count for this child reached */ + if ((pool_config->child_max_connections > 0) && + (connections_count >= pool_config->child_max_connections)) + { + ereport(LOG, + (errmsg("child exiting, %d connections reached", pool_config->child_max_connections))); child_exit(POOL_EXIT_AND_RESTART); - } - } + } + } - if(child_frontend) + if (child_frontend) { pool_close(child_frontend); child_frontend = NULL; @@ -278,8 +284,8 @@ void do_child(int *fds) for (;;) { StartupPacket *sp; - int front_end_fd; - SockAddr saddr; + int front_end_fd; + SockAddr saddr; /* reset per iteration memory context */ MemoryContextSwitchTo(ProcessLoopContext); @@ -296,18 +302,18 @@ void do_child(int *fds) pool_session_context_destroy(); front_end_fd = wait_for_new_connections(fds, &timeout, &saddr); - if(front_end_fd == OPERATION_TIMEOUT) + if (front_end_fd == OPERATION_TIMEOUT) { - if(pool_config->child_life_time > 0 && connected) + if (pool_config->child_life_time > 0 && connected) { ereport(DEBUG1, - (errmsg("child life %d seconds expired", pool_config->child_life_time))); + (errmsg("child life %d seconds expired", pool_config->child_life_time))); child_exit(POOL_EXIT_AND_RESTART); } continue; } - if(front_end_fd == RETRY) + if (front_end_fd == RETRY) continue; connection_count_up(); @@ -331,21 +337,22 @@ void do_child(int *fds) } backend = get_backend_connection(child_frontend); - if(!backend) + if (!backend) { pool_close(child_frontend); child_frontend = NULL; continue; } connected = 1; - + /* - * show ps status + * show ps status */ sp = MASTER_CONNECTION(backend)->sp; snprintf(psbuf, sizeof(psbuf), "%s %s %s idle", - sp->user, sp->database, remote_ps_data); + sp->user, sp->database, remote_ps_data); set_ps_display(psbuf, false); + /* * Initialize per session context */ @@ -358,30 +365,31 @@ void do_child(int *fds) pool_set_minor_version(sp->minor); /* - * Mark this connection pool is connected from frontend + * Mark this connection pool is connected from frontend */ pool_coninfo_set_frontend_connected(pool_get_process_context()->proc_id, pool_pool_index()); /* create memory context for query processing */ QueryContext = AllocSetContextCreate(ProcessLoopContext, - "child_query_process", - ALLOCSET_DEFAULT_MINSIZE, - ALLOCSET_DEFAULT_INITSIZE, - ALLOCSET_DEFAULT_MAXSIZE); - /* query process loop */ + "child_query_process", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + /* query process loop */ for (;;) { POOL_STATUS status; + /* Reset the query process memory context */ MemoryContextSwitchTo(QueryContext); MemoryContextResetAndDeleteChildren(QueryContext); status = pool_process_query(child_frontend, backend, 0); - if(status != POOL_CONTINUE) - { - backend_cleanup(&child_frontend, backend, false); - break; - } + if (status != POOL_CONTINUE) + { + backend_cleanup(&child_frontend, backend, false); + break; + } } /* Destroy session context */ @@ -397,12 +405,12 @@ void do_child(int *fds) timeout.tv_usec = 0; /* increment queries counter if necessary */ - if ( pool_config->child_max_connections > 0 ) + if (pool_config->child_max_connections > 0) connections_count++; /* check if maximum connections count for this child reached */ - if ( ( pool_config->child_max_connections > 0 ) && - ( connections_count >= pool_config->child_max_connections ) ) + if ((pool_config->child_max_connections > 0) && + (connections_count >= pool_config->child_max_connections)) { ereport(LOG, (errmsg("child exiting, %d connections reached", pool_config->child_max_connections))); @@ -422,59 +430,61 @@ void do_child(int *fds) * return true if backend connection is cached */ static bool -backend_cleanup(POOL_CONNECTION* volatile *frontend, POOL_CONNECTION_POOL* volatile backend, bool frontend_invalid) +backend_cleanup(POOL_CONNECTION * volatile *frontend, POOL_CONNECTION_POOL * volatile backend, bool frontend_invalid) { - StartupPacket *sp; - bool cache_connection = false; + StartupPacket *sp; + bool cache_connection = false; - if (backend == NULL) - return false; + if (backend == NULL) + return false; - sp = MASTER_CONNECTION(backend)->sp; + sp = MASTER_CONNECTION(backend)->sp; - /* - * cach connection if connection cache configuration parameter is enabled + /* + * cach connection if connection cache configuration parameter is enabled * and frontend connection is not invalid - */ - if (sp && pool_config->connection_cache != 0 && frontend_invalid == false ) - { - if (*frontend) - { - MemoryContext oldContext = CurrentMemoryContext; - PG_TRY(); - { - if(pool_process_query(*frontend, backend, 1) == POOL_CONTINUE) - { - pool_connection_pool_timer(backend); - cache_connection = true; - } - } - PG_CATCH(); - { - /* ignore the error message */ - MemoryContextSwitchTo(oldContext); - FlushErrorState(); - } - PG_END_TRY(); - } - } + */ + if (sp && pool_config->connection_cache != 0 && frontend_invalid == false) + { + if (*frontend) + { + MemoryContext oldContext = CurrentMemoryContext; + + PG_TRY(); + { + if (pool_process_query(*frontend, backend, 1) == POOL_CONTINUE) + { + pool_connection_pool_timer(backend); + cache_connection = true; + } + } + PG_CATCH(); + { + /* ignore the error message */ + MemoryContextSwitchTo(oldContext); + FlushErrorState(); + } + PG_END_TRY(); + } + } if (cache_connection) { /* - * For those special databases, and when frontend client exits abnormally, - * we don't cache connection to backend. + * For those special databases, and when frontend client exits + * abnormally, we don't cache connection to backend. */ if ((sp && - (!strcmp(sp->database, "template0") || - !strcmp(sp->database, "template1") || - !strcmp(sp->database, "postgres") || - !strcmp(sp->database, "regression"))) || - (*frontend != NULL && - ((*frontend)->socket_state == POOL_SOCKET_EOF || + (!strcmp(sp->database, "template0") || + !strcmp(sp->database, "template1") || + !strcmp(sp->database, "postgres") || + !strcmp(sp->database, "regression"))) || + (*frontend != NULL && + ((*frontend)->socket_state == POOL_SOCKET_EOF || (*frontend)->socket_state == POOL_SOCKET_ERROR))) cache_connection = false; } + /* * Close frontend connection */ @@ -482,16 +492,16 @@ backend_cleanup(POOL_CONNECTION* volatile *frontend, POOL_CONNECTION_POOL* volat pool_close(*frontend); *frontend = NULL; - if (cache_connection == false) - { + if (cache_connection == false) + { pool_send_frontend_exits(backend); - if(sp) - pool_discard_cp(sp->user, sp->database, sp->major); - } + if (sp) + pool_discard_cp(sp->user, sp->database, sp->major); + } /* reset the config parameters */ - reset_all_variables(NULL,NULL); - return cache_connection; + reset_all_variables(NULL, NULL); + return cache_connection; } /* @@ -499,59 +509,60 @@ backend_cleanup(POOL_CONNECTION* volatile *frontend, POOL_CONNECTION_POOL* volat * * Read the startup packet and parse the contents. */ -static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) +static StartupPacket * +read_startup_packet(POOL_CONNECTION * cp) { StartupPacket *sp; StartupPacket_v2 *sp2; - int protov; - int len; - char *p; + int protov; + int len; + char *p; - sp = (StartupPacket *)palloc0(sizeof(*sp)); + sp = (StartupPacket *) palloc0(sizeof(*sp)); enable_authentication_timeout(); /* read startup packet length */ - pool_read_with_error(cp, &len, sizeof(len), - "startup packet length"); + pool_read_with_error(cp, &len, sizeof(len), + "startup packet length"); len = ntohl(len); len -= sizeof(len); if (len <= 0 || len >= MAX_STARTUP_PACKET_LENGTH) ereport(ERROR, - (errmsg("failed while reading startup packet"), + (errmsg("failed while reading startup packet"), errdetail("incorrect packet length (%d)", len))); sp->startup_packet = palloc0(len); /* read startup packet */ - pool_read_with_error(cp, sp->startup_packet, len, - "startup packet"); + pool_read_with_error(cp, sp->startup_packet, len, + "startup packet"); sp->len = len; memcpy(&protov, sp->startup_packet, sizeof(protov)); - sp->major = ntohl(protov)>>16; + sp->major = ntohl(protov) >> 16; sp->minor = ntohl(protov) & 0x0000ffff; p = sp->startup_packet; - cp->protoVersion = sp->major; + cp->protoVersion = sp->major; - switch(sp->major) + switch (sp->major) { - case PROTO_MAJOR_V2: /* V2 */ - sp2 = (StartupPacket_v2 *)(sp->startup_packet); + case PROTO_MAJOR_V2: /* V2 */ + sp2 = (StartupPacket_v2 *) (sp->startup_packet); - sp->database = palloc0(SM_DATABASE+1); + sp->database = palloc0(SM_DATABASE + 1); strncpy(sp->database, sp2->database, SM_DATABASE); - sp->user = palloc0(SM_USER+1); + sp->user = palloc0(SM_USER + 1); strncpy(sp->user, sp2->user, SM_USER); break; - case PROTO_MAJOR_V3: /* V3 */ + case PROTO_MAJOR_V3: /* V3 */ p += sizeof(int); /* skip protocol version info */ - while(*p) + while (*p) { if (!strcmp("user", p)) { @@ -565,21 +576,19 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) } /* - * From 9.0, the start up packet may include - * application name. After receiving such that packet, - * backend sends parameter status of application_name. - * Upon reusing connection to backend, we need to - * emulate this behavior of backend. So we remember - * this and send parameter status packet to frontend - * instead of backend in - * connect_using_existing_connection(). + * From 9.0, the start up packet may include application name. + * After receiving such that packet, backend sends parameter + * status of application_name. Upon reusing connection to + * backend, we need to emulate this behavior of backend. So we + * remember this and send parameter status packet to frontend + * instead of backend in connect_using_existing_connection(). */ else if (!strcmp("application_name", p)) { p += (strlen(p) + 1); sp->application_name = p; ereport(DEBUG1, - (errmsg("reading startup packet"), + (errmsg("reading startup packet"), errdetail("application_name: %s", p))); } @@ -587,7 +596,7 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) } break; - case 1234: /* cancel or SSL request */ + case 1234: /* cancel or SSL request */ /* set dummy database, user info */ sp->database = palloc0(1); sp->user = palloc(1); @@ -595,22 +604,22 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) default: ereport(ERROR, - (errmsg("failed while reading startup packet"), + (errmsg("failed while reading startup packet"), errdetail("invalid major no: %d in startup packet", sp->major))); } /* Check a user name was given. */ if (sp->major != 1234 && - (sp->user == NULL || sp->user[0] == '\0')) + (sp->user == NULL || sp->user[0] == '\0')) { pool_send_fatal_message(cp, sp->major, "28000", - "no PostgreSQL user name specified in startup packet", + "no PostgreSQL user name specified in startup packet", "", "", __FILE__, __LINE__); ereport(FATAL, - (errmsg("failed while reading startup packet"), - errdetail("no PostgreSQL user name specified in startup packet"))); + (errmsg("failed while reading startup packet"), + errdetail("no PostgreSQL user name specified in startup packet"))); } /* The database defaults to ther user name. */ @@ -620,9 +629,9 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) } ereport(DEBUG1, - (errmsg("reading startup packet"), - errdetail("Protocol Major: %d Minor: %d database: %s user: %s", - sp->major, sp->minor, sp->database, sp->user))); + (errmsg("reading startup packet"), + errdetail("Protocol Major: %d Minor: %d database: %s user: %s", + sp->major, sp->minor, sp->database, sp->user))); disable_authentication_timeout(); @@ -632,9 +641,10 @@ static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) /* * send startup packet */ -void send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp) +void +send_startup_packet(POOL_CONNECTION_POOL_SLOT * cp) { - int len; + int len; len = htonl(cp->sp->len + sizeof(len)); pool_write(cp->con, &len, sizeof(len)); @@ -645,12 +655,14 @@ void send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp) * Reuse existing connection */ static bool -connect_using_existing_connection(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - StartupPacket *sp) +connect_using_existing_connection(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + StartupPacket *sp) { - int i, freed = 0; - StartupPacket *topmem_sp = NULL; + int i, + freed = 0; + StartupPacket *topmem_sp = NULL; + /* * Save startup packet info */ @@ -661,11 +673,12 @@ connect_using_existing_connection(POOL_CONNECTION *frontend, if (!freed) { MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + topmem_sp = StartupPacketCopy(sp); MemoryContextSwitchTo(oldContext); pool_free_startup_packet(backend->slots[i]->sp); - backend->slots[i]->sp = NULL; + backend->slots[i]->sp = NULL; freed = 1; } @@ -679,27 +692,28 @@ connect_using_existing_connection(POOL_CONNECTION *frontend, if (MAJOR(backend) == 3) { - char command_buf[1024]; + char command_buf[1024]; - /* If we have received application_name in the start up - * packet, we send SET command to backend. Also we add or - * replace existing application_name data. + /* + * If we have received application_name in the start up packet, we + * send SET command to backend. Also we add or replace existing + * application_name data. */ if (sp->application_name) { snprintf(command_buf, sizeof(command_buf), "SET application_name TO '%s'", sp->application_name); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) if (do_command(frontend, CONNECTION(backend, i), - command_buf, MAJOR(backend), + command_buf, MAJOR(backend), MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) { - ereport(ERROR, - (errmsg("unable to process command for backend connection"), - errdetail("do_command returned DEADLOCK status"))); + ereport(ERROR, + (errmsg("unable to process command for backend connection"), + errdetail("do_command returned DEADLOCK status"))); } } @@ -714,8 +728,8 @@ connect_using_existing_connection(POOL_CONNECTION *frontend, if (MAJOR(backend) == 3) { - int len; - char tstate; + int len; + char tstate; len = htonl(5); pool_write(frontend, &len, sizeof(len)); @@ -731,40 +745,43 @@ connect_using_existing_connection(POOL_CONNECTION *frontend, /* * process cancel request */ -void cancel_request(CancelPacket *sp) +void +cancel_request(CancelPacket * sp) { - int len; - int fd; + int len; + int fd; POOL_CONNECTION *con; - int i,j,k; + int i, + j, + k; ConnectionInfo *c = NULL; CancelPacket cp; - bool found = false; + bool found = false; if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Cancel message from frontend."), - errdetail("process id: %d", ntohl(sp->pid) ))); - ereport(DEBUG1, - (errmsg("Cancel request received"))); + (errmsg("Cancel message from frontend."), + errdetail("process id: %d", ntohl(sp->pid)))); + ereport(DEBUG1, + (errmsg("Cancel request received"))); /* look for cancel key from shmem info */ - for (i=0;i<pool_config->num_init_children;i++) + for (i = 0; i < pool_config->num_init_children; i++) { - for (j=0;j<pool_config->max_pool;j++) + for (j = 0; j < pool_config->max_pool; j++) { - for (k=0;k<NUM_BACKENDS;k++) + for (k = 0; k < NUM_BACKENDS; k++) { c = pool_coninfo(i, j, k); ereport(DEBUG2, - (errmsg("processing cancel request"), + (errmsg("processing cancel request"), errdetail("connection info: address:%p database:%s user:%s pid:%d key:%d i:%d", - c, c->database, c->user, ntohl(c->pid), ntohl(c->key),i))); + c, c->database, c->user, ntohl(c->pid), ntohl(c->key), i))); if (c->pid == sp->pid && c->key == sp->key) { ereport(DEBUG1, - (errmsg("processing cancel request"), - errdetail("found pid:%d key:%d i:%d",ntohl(c->pid), ntohl(c->key),i))); + (errmsg("processing cancel request"), + errdetail("found pid:%d key:%d i:%d", ntohl(c->pid), ntohl(c->key), i))); c = pool_coninfo(i, j, 0); found = true; @@ -774,15 +791,15 @@ void cancel_request(CancelPacket *sp) } } - found: +found: if (!found) { ereport(LOG, - (errmsg("invalid cancel key: pid:%d key:%d",ntohl(sp->pid), ntohl(sp->key)))); - return; /* invalid key */ + (errmsg("invalid cancel key: pid:%d key:%d", ntohl(sp->pid), ntohl(sp->key)))); + return; /* invalid key */ } - for (i=0;i<NUM_BACKENDS;i++,c++) + for (i = 0; i < NUM_BACKENDS; i++, c++) { if (!VALID_BACKEND(i)) continue; @@ -799,7 +816,7 @@ void cancel_request(CancelPacket *sp) return; } - con = pool_open(fd,true); + con = pool_open(fd, true); if (con == NULL) return; @@ -813,35 +830,36 @@ void cancel_request(CancelPacket *sp) cp.key = c->key; ereport(LOG, - (errmsg("forwarding cancel request to backend"), - errdetail("canceling backend pid:%d key: %d", ntohl(cp.pid),ntohl(cp.key)))); + (errmsg("forwarding cancel request to backend"), + errdetail("canceling backend pid:%d key: %d", ntohl(cp.pid), ntohl(cp.key)))); if (pool_write_and_flush_noerror(con, &cp, sizeof(CancelPacket)) < 0) ereport(WARNING, - (errmsg("failed to send cancel request to backend %d",i))); + (errmsg("failed to send cancel request to backend %d", i))); pool_close(con); /* - * this is needed to ensure that the next DB node executes the - * query supposed to be canceled. + * this is needed to ensure that the next DB node executes the query + * supposed to be canceled. */ sleep(1); } } -static StartupPacket *StartupPacketCopy(StartupPacket *sp) +static StartupPacket * +StartupPacketCopy(StartupPacket *sp) { StartupPacket *new_sp; /* verify the length first */ if (sp->len <= 0 || sp->len >= MAX_STARTUP_PACKET_LENGTH) ereport(ERROR, - (errmsg("incorrect packet length (%d)", sp->len))); + (errmsg("incorrect packet length (%d)", sp->len))); - new_sp = (StartupPacket *)palloc0(sizeof(*sp)); + new_sp = (StartupPacket *) palloc0(sizeof(*sp)); new_sp->startup_packet = palloc0(sp->len); - memcpy(new_sp->startup_packet,sp->startup_packet,sp->len); + memcpy(new_sp->startup_packet, sp->startup_packet, sp->len); new_sp->len = sp->len; new_sp->major = sp->major; @@ -850,7 +868,7 @@ static StartupPacket *StartupPacketCopy(StartupPacket *sp) new_sp->database = pstrdup(sp->database); new_sp->user = pstrdup(sp->user); - if(new_sp->major == PROTO_MAJOR_V3 && sp->application_name) + if (new_sp->major == PROTO_MAJOR_V3 && sp->application_name) { /* adjust the application name pointer in new packet */ new_sp->application_name = new_sp->startup_packet + (sp->application_name - sp->startup_packet); @@ -858,11 +876,11 @@ static StartupPacket *StartupPacketCopy(StartupPacket *sp) return new_sp; } -static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend) +static POOL_CONNECTION_POOL * connect_backend(StartupPacket *sp, POOL_CONNECTION * frontend) { POOL_CONNECTION_POOL *backend; StartupPacket *topmem_sp; - int i; + int i; /* connect to the backend */ backend = pool_create_cp(); @@ -871,18 +889,19 @@ static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION pool_send_error_message(frontend, sp->major, "XX000", "connection cache is full", "", "increase max_pool", __FILE__, __LINE__); ereport(ERROR, - (errmsg("unable to connect to backend"), - errdetail("connection cache is full"), - errhint("increase the \"max_pool\" configuration value, current max_pool is %d",pool_config->max_pool))); + (errmsg("unable to connect to backend"), + errdetail("connection cache is full"), + errhint("increase the \"max_pool\" configuration value, current max_pool is %d", pool_config->max_pool))); } - + PG_TRY(); { MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + topmem_sp = StartupPacketCopy(sp); MemoryContextSwitchTo(oldContext); - for (i=0; i < NUM_BACKENDS; i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -904,6 +923,7 @@ static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION send_startup_packet(CONNECTION_SLOT(backend, i)); } } + /* * do authentication stuff */ @@ -924,7 +944,7 @@ static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION */ static RETSIGTYPE die(int sig) { - int save_errno; + int save_errno; POOL_SETMASK(&BlockSig); @@ -939,7 +959,7 @@ static RETSIGTYPE die(int sig) switch (sig) { - case SIGTERM: /* smart shutdown */ + case SIGTERM: /* smart shutdown */ /* Refuse further requests by closing listen socket */ if (child_inet_fd) { @@ -960,15 +980,15 @@ static RETSIGTYPE die(int sig) } break; - case SIGINT: /* fast shutdown */ - case SIGQUIT: /* immediate shutdown */ + case SIGINT: /* fast shutdown */ + case SIGQUIT: /* immediate shutdown */ POOL_SETMASK(&UnBlockSig); child_exit(POOL_EXIT_NO_RESTART); break; default: #ifdef NOT_USED ereport(LOG, - (errmsg("child process received unknown signal: %d",sig), + (errmsg("child process received unknown signal: %d", sig), errdetail("ignoring..."))); #endif break; @@ -984,26 +1004,27 @@ static RETSIGTYPE die(int sig) */ static RETSIGTYPE close_idle_connection(int sig) { - int i, j; + int i, + j; POOL_CONNECTION_POOL *p = pool_connection_pool; ConnectionInfo *info; - int save_errno = errno; + int save_errno = errno; #ifdef NOT_USED ereport(DEBUG1, (errmsg("close connection request received"))); #endif - for (j=0;j<pool_config->max_pool;j++, p++) + for (j = 0; j < pool_config->max_pool; j++, p++) { if (!MASTER_CONNECTION(p)) continue; - if (!MASTER_CONNECTION(p)->sp) + if (!MASTER_CONNECTION(p)->sp) continue; if (MASTER_CONNECTION(p)->sp->user == NULL) continue; - if (MASTER_CONNECTION(p)->closetime > 0) /* idle connection? */ + if (MASTER_CONNECTION(p)->closetime > 0) /* idle connection? */ { #ifdef NOT_USED ereport(DEBUG1, @@ -1013,16 +1034,19 @@ static RETSIGTYPE close_idle_connection(int sig) pool_send_frontend_exits(p); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; if (i == 0) { - /* only first backend allocated the memory for the start up packet */ + /* + * only first backend allocated the memory for the start + * up packet + */ pool_free_startup_packet(CONNECTION_SLOT(p, i)->sp); - CONNECTION_SLOT(p, i)->sp = NULL; + CONNECTION_SLOT(p, i)->sp = NULL; } pool_close(CONNECTION(p, i)); @@ -1050,17 +1074,19 @@ static RETSIGTYPE authentication_timeout(int sig) child_exit(POOL_EXIT_AND_RESTART); } -static void enable_authentication_timeout(void) +static void +enable_authentication_timeout(void) { - if(pool_config->authentication_timeout <= 0) + if (pool_config->authentication_timeout <= 0) return; pool_alarm(authentication_timeout, pool_config->authentication_timeout); alarm_enabled = true; } -static void disable_authentication_timeout(void) +static void +disable_authentication_timeout(void) { - if(alarm_enabled) + if (alarm_enabled) { pool_undo_alarm(); alarm_enabled = false; @@ -1072,16 +1098,17 @@ static void disable_authentication_timeout(void) * in any case when child process exits, for example failover, child * life time expires or child max connections expires. */ -static void send_frontend_exits(void) +static void +send_frontend_exits(void) { - int i; + int i; POOL_CONNECTION_POOL *p = pool_connection_pool; pool_sigset_t oldmask; POOL_SETMASK2(&BlockSig, &oldmask); - for (i=0;i<pool_config->max_pool;i++, p++) + for (i = 0; i < pool_config->max_pool; i++, p++) { if (!MASTER_CONNECTION(p)) continue; @@ -1096,11 +1123,13 @@ static void send_frontend_exits(void) } static void -send_params(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +send_params(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - int index; - char *name, *value; - int len, sendlen; + int index; + char *name, + *value; + int len, + sendlen; index = 0; while (pool_get_param(&MASTER(backend)->params, index++, &name, &value) == 0) @@ -1115,13 +1144,14 @@ send_params(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) if (pool_flush(frontend)) { - ereport(ERROR, - (errmsg("unable to send params to frontend"), - errdetail("pool_flush failed"))); + ereport(ERROR, + (errmsg("unable to send params to frontend"), + errdetail("pool_flush failed"))); } } -void pool_free_startup_packet(StartupPacket *sp) +void +pool_free_startup_packet(StartupPacket *sp) { if (sp) { @@ -1142,39 +1172,41 @@ void pool_free_startup_packet(StartupPacket *sp) static void child_will_go_down(int code, Datum arg) { - if(processType != PT_CHILD) + if (processType != PT_CHILD) { /* should never happen */ ereport(WARNING, (errmsg("child_exit: called from invalid process. ignored."))); return; } - + /* count down global connection counter */ if (accepted) connection_count_down(); - + if (pool_config->memory_cache_enabled && !pool_is_shmem_cache()) { memcached_disconnect(); } - + /* let backend know now we are exiting */ if (pool_connection_pool) send_frontend_exits(); } -void child_exit(int code) +void +child_exit(int code) { - if(processType != PT_CHILD) + if (processType != PT_CHILD) { /* should never happen */ - /* Remove call to ereport because child_exit() is called inside a + /* + * Remove call to ereport because child_exit() is called inside a * signal handler. */ #ifdef NOT_USED - ereport(WARNING, - (errmsg("child_exit: called from invalid process. ignored."))); + ereport(WARNING, + (errmsg("child_exit: called from invalid process. ignored."))); #endif return; } @@ -1184,26 +1216,30 @@ void child_exit(int code) /* * create a persistent connection */ -POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( - int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry) +POOL_CONNECTION_POOL_SLOT * +make_persistent_db_connection( + int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry) { POOL_CONNECTION_POOL_SLOT *cp; - int fd; + int fd; #define MAX_USER_AND_DATABASE 1024 /* V3 startup packet */ - typedef struct { - int protoVersion; - char data[MAX_USER_AND_DATABASE]; - } StartupPacket_v3; + typedef struct + { + int protoVersion; + char data[MAX_USER_AND_DATABASE]; + } StartupPacket_v3; - static StartupPacket_v3 *startup_packet; - int len, len1; + static StartupPacket_v3 * startup_packet; + int len, + len1; cp = palloc0(sizeof(POOL_CONNECTION_POOL_SLOT)); startup_packet = palloc0(sizeof(*startup_packet)); - startup_packet->protoVersion = htonl(0x00030000); /* set V3 proto major/minor */ + startup_packet->protoVersion = htonl(0x00030000); /* set V3 proto + * major/minor */ /* * create socket @@ -1221,12 +1257,12 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( { free_persisten_db_connection_memory(cp); pfree(startup_packet); - ereport(ERROR, - (errmsg("failed to make persistent db connection"), - errdetail("connection to host:\"%s:%d\" failed", hostname, port))); + ereport(ERROR, + (errmsg("failed to make persistent db connection"), + errdetail("connection to host:\"%s:%d\" failed", hostname, port))); } - cp->con = pool_open(fd,true); + cp->con = pool_open(fd, true); cp->closetime = 0; cp->con->isbackend = 1; pool_set_db_node_id(cp->con, db_node_id); @@ -1237,46 +1273,46 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( * build V3 startup packet */ len = snprintf(startup_packet->data, sizeof(startup_packet->data), "user") + 1; - len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "%s", user) + 1; - if (len1 >= (sizeof(startup_packet->data)-len)) + len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data) - len, "%s", user) + 1; + if (len1 >= (sizeof(startup_packet->data) - len)) { pool_close(cp->con); free_persisten_db_connection_memory(cp); pfree(startup_packet); - ereport(ERROR, - (errmsg("failed to make persistent db connection"), - errdetail("user name is too long"))); + ereport(ERROR, + (errmsg("failed to make persistent db connection"), + errdetail("user name is too long"))); } len += len1; - len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "database") + 1; - if (len1 >= (sizeof(startup_packet->data)-len)) + len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data) - len, "database") + 1; + if (len1 >= (sizeof(startup_packet->data) - len)) { pool_close(cp->con); free_persisten_db_connection_memory(cp); pfree(startup_packet); - ereport(ERROR, - (errmsg("failed to make persistent db connection"), - errdetail("user name is too long"))); + ereport(ERROR, + (errmsg("failed to make persistent db connection"), + errdetail("user name is too long"))); } len += len1; - len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data)-len, "%s", dbname) + 1; - if (len1 >= (sizeof(startup_packet->data)-len)) + len1 = snprintf(&startup_packet->data[len], sizeof(startup_packet->data) - len, "%s", dbname) + 1; + if (len1 >= (sizeof(startup_packet->data) - len)) { pool_close(cp->con); free_persisten_db_connection_memory(cp); pfree(startup_packet); - ereport(ERROR, - (errmsg("failed to make persistent db connection"), - errdetail("database name is too long"))); + ereport(ERROR, + (errmsg("failed to make persistent db connection"), + errdetail("database name is too long"))); } len += len1; startup_packet->data[len++] = '\0'; cp->sp = palloc(sizeof(StartupPacket)); - cp->sp->startup_packet = (char *)startup_packet; + cp->sp->startup_packet = (char *) startup_packet; cp->sp->len = len + 4; cp->sp->major = 3; cp->sp->minor = 0; @@ -1306,35 +1342,39 @@ POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection( * make_persistent_db_connection_noerror() is a wrapper over * make_persistent_db_connection() which does not ereports in case of an error */ -POOL_CONNECTION_POOL_SLOT *make_persistent_db_connection_noerror( - int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry) +POOL_CONNECTION_POOL_SLOT * +make_persistent_db_connection_noerror( + int db_node_id, char *hostname, int port, char *dbname, char *user, char *password, bool retry) { - POOL_CONNECTION_POOL_SLOT *slot = NULL; - MemoryContext oldContext = CurrentMemoryContext; - PG_TRY(); - { - slot = make_persistent_db_connection(db_node_id, + POOL_CONNECTION_POOL_SLOT *slot = NULL; + MemoryContext oldContext = CurrentMemoryContext; + + PG_TRY(); + { + slot = make_persistent_db_connection(db_node_id, hostname, port, dbname, user, password, retry); - } - PG_CATCH(); - { - EmitErrorReport(); - MemoryContextSwitchTo(oldContext); - FlushErrorState(); - slot = NULL; - } - PG_END_TRY(); - return slot; + } + PG_CATCH(); + { + EmitErrorReport(); + MemoryContextSwitchTo(oldContext); + FlushErrorState(); + slot = NULL; + } + PG_END_TRY(); + return slot; } + /* * Free memory of POOL_CONNECTION_POOL_SLOT. Should only be used in * make_persistent_db_connection and discard_persistent_db_connection. */ -void free_persisten_db_connection_memory(POOL_CONNECTION_POOL_SLOT *cp) +void +free_persisten_db_connection_memory(POOL_CONNECTION_POOL_SLOT * cp) { if (!cp) return; @@ -1357,11 +1397,12 @@ void free_persisten_db_connection_memory(POOL_CONNECTION_POOL_SLOT *cp) * Discard connection and memory allocated by * make_persistent_db_connection(). */ -void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp) +void +discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT * cp) { - int len; + int len; - if(cp == NULL) + if (cp == NULL) return; pool_write(cp->con, "X", 1); @@ -1369,11 +1410,10 @@ void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp) pool_write(cp->con, &len, sizeof(len)); /* - * XXX we cannot call pool_flush() here since backend may already - * close the socket and pool_flush() automatically invokes fail - * over handler. This could happen in copy command (remember the - * famous "lost synchronization with server, resetting - * connection" message) + * XXX we cannot call pool_flush() here since backend may already close + * the socket and pool_flush() automatically invokes fail over handler. + * This could happen in copy command (remember the famous "lost + * synchronization with server, resetting connection" message) */ pool_set_nonblock(cp->con->fd); pool_flush_it(cp->con); @@ -1387,7 +1427,8 @@ void discard_persistent_db_connection(POOL_CONNECTION_POOL_SLOT *cp) * Count up connection counter (from frontend to pgpool) * in shared memory */ -static void connection_count_up(void) +static void +connection_count_up(void) { pool_sigset_t oldmask; @@ -1402,19 +1443,20 @@ static void connection_count_up(void) * Count down connection counter (from frontend to pgpool) * in shared memory */ -static void connection_count_down(void) +static void +connection_count_down(void) { pool_sigset_t oldmask; POOL_SETMASK2(&BlockSig, &oldmask); pool_semaphore_lock(CONN_COUNTER_SEM); + /* - * Make sure that we do not decrement too much. If failed to read - * a start up packet, or receive cancel request etc., - * connection_count_down() is called and goes back to the - * connection accept loop. Problem is, at the very beginning of - * the connection accept loop, if we have received a signal, we - * call child_exit() which calls connection_count_down() again. + * Make sure that we do not decrement too much. If failed to read a start + * up packet, or receive cancel request etc., connection_count_down() is + * called and goes back to the connection accept loop. Problem is, at the + * very beginning of the connection accept loop, if we have received a + * signal, we call child_exit() which calls connection_count_down() again. */ if (Req_info->conn_counter > 0) Req_info->conn_counter--; @@ -1436,27 +1478,30 @@ static RETSIGTYPE wakeup_handler(int sig) * 1) client connects * 2) the node previously selected for the load balance node is down */ -int select_load_balancing_node(void) +int +select_load_balancing_node(void) { - int selected_slot; - double total_weight,r; - int i; - int index_db = -1, index_app = -1; + int selected_slot; + double total_weight, + r; + int i; + int index_db = -1, + index_app = -1; POOL_SESSION_CONTEXT *ses = pool_get_session_context(false); - int tmp; - int no_load_balance_node_id = -2; + int tmp; + int no_load_balance_node_id = -2; /* * -2 indicates there's no database_redirect_preference_list. -1 indicates * database_redirect_preference_list exists and any of standby nodes * specified. */ - int suggested_node_id = -2; + int suggested_node_id = -2; #if defined(sun) || defined(__sun) - r = (((double)rand())/RAND_MAX); + r = (((double) rand()) / RAND_MAX); #else - r = (((double)random())/RAND_MAX); + r = (((double) random()) / RAND_MAX); #endif /* @@ -1464,9 +1509,10 @@ int select_load_balancing_node(void) */ if (SL_MODE && pool_config->redirect_dbnames) { - char *database = MASTER_CONNECTION(ses->backend)->sp->database; + char *database = MASTER_CONNECTION(ses->backend)->sp->database; - /* Check to see if the database matches any of + /* + * Check to see if the database matches any of * database_redirect_preference_list */ index_db = regex_array_match(pool_config->redirect_dbnames, database); @@ -1476,8 +1522,8 @@ int select_load_balancing_node(void) ereport(DEBUG1, (errmsg("selecting load balance node db matched"), errdetail("dbname: %s index is %d dbnode is %s weight is %f", database, index_db, - pool_config->db_redirect_tokens->token[index_db].right_token, - pool_config->db_redirect_tokens->token[index_db].weight_token))); + pool_config->db_redirect_tokens->token[index_db].right_token, + pool_config->db_redirect_tokens->token[index_db].weight_token))); tmp = choose_db_node_id(pool_config->db_redirect_tokens->token[index_db].right_token); if (tmp == -1 || (tmp >= 0 && VALID_BACKEND(tmp))) @@ -1490,11 +1536,11 @@ int select_load_balancing_node(void) */ if (SL_MODE && pool_config->redirect_app_names) { - char *app_name = MASTER_CONNECTION(ses->backend)->sp->application_name; + char *app_name = MASTER_CONNECTION(ses->backend)->sp->application_name; /* - * Check only if application name is set. - * Old applications may not have application name. + * Check only if application name is set. Old applications may not + * have application name. */ if (app_name && strlen(app_name) > 0) { @@ -1507,7 +1553,8 @@ int select_load_balancing_node(void) { /* - * if the aplication name matches any of app_name_redirect_preference_list, + * if the aplication name matches any of + * app_name_redirect_preference_list, * database_redirect_preference_list will be ignored. */ index_db = -1; @@ -1516,8 +1563,8 @@ int select_load_balancing_node(void) ereport(DEBUG1, (errmsg("selecting load balance node db matched"), errdetail("app_name: %s index is %d dbnode is %s weight is %f", app_name, index_app, - pool_config->app_name_redirect_tokens->token[index_app].right_token, - pool_config->app_name_redirect_tokens->token[index_app].weight_token))); + pool_config->app_name_redirect_tokens->token[index_app].right_token, + pool_config->app_name_redirect_tokens->token[index_app].weight_token))); tmp = choose_db_node_id(pool_config->app_name_redirect_tokens->token[index_app].right_token); if (tmp == -1 || (tmp >= 0 && VALID_BACKEND(tmp))) @@ -1529,8 +1576,9 @@ int select_load_balancing_node(void) if (suggested_node_id >= 0) { /* - * If the weight is bigger than random rate then send to suggested_node_id. - * If the weight is less than random rate then choose load balance node from other nodes. + * If the weight is bigger than random rate then send to + * suggested_node_id. If the weight is less than random rate then + * choose load balance node from other nodes. */ if ((index_db >= 0 && r <= pool_config->db_redirect_tokens->token[index_db].weight_token) || (index_app >= 0 && r <= pool_config->app_name_redirect_tokens->token[index_app].weight_token)) @@ -1562,7 +1610,7 @@ int select_load_balancing_node(void) selected_slot = MASTER_NODE_ID; total_weight = 0.0; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -1579,20 +1627,20 @@ int select_load_balancing_node(void) } #if defined(sun) || defined(__sun) - r = (((double)rand())/RAND_MAX) * total_weight; + r = (((double) rand()) / RAND_MAX) * total_weight; #else - r = (((double)random())/RAND_MAX) * total_weight; + r = (((double) random()) / RAND_MAX) * total_weight; #endif total_weight = 0.0; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if ((suggested_node_id == -1 && i == PRIMARY_NODE_ID) || i == no_load_balance_node_id) continue; if (VALID_BACKEND(i) && BACKEND_INFO(i).backend_weight > 0.0) { - if(r >= total_weight) + if (r >= total_weight) selected_slot = i; else break; @@ -1600,7 +1648,7 @@ int select_load_balancing_node(void) } } ereport(DEBUG1, - (errmsg("selecting load balance node"), + (errmsg("selecting load balance node"), errdetail("selected backend id is %d", selected_slot))); return selected_slot; } @@ -1614,11 +1662,12 @@ static RETSIGTYPE reload_config_handler(int sig) /* * Exit myself if SIGTERM, SIGINT or SIGQUIT has been sent */ -void check_stop_request(void) +void +check_stop_request(void) { - /* - * If smart shutdown was requested but we are not in idle state, - * do not exit + /* + * If smart shutdown was requested but we are not in idle state, do not + * exit */ if (exit_request == SIGTERM && idle == 0) return; @@ -1635,14 +1684,15 @@ void check_stop_request(void) * We copy the backend status to private area so that * they are not changed while I am alive. */ -void pool_initialize_private_backend_status(void) +void +pool_initialize_private_backend_status(void) { - int i; + int i; ereport(DEBUG1, - (errmsg("initializing backend status"))); + (errmsg("initializing backend status"))); - for (i=0;i<MAX_NUM_BACKENDS;i++) + for (i = 0; i < MAX_NUM_BACKENDS; i++) { private_backend_status[i] = BACKEND_INFO(i).backend_status; /* my_backend_status is referred to by VALID_BACKEND macro. */ @@ -1652,16 +1702,17 @@ void pool_initialize_private_backend_status(void) my_master_node_id = REAL_MASTER_NODE_ID; } -static void check_restart_request(void) +static void +check_restart_request(void) { - /* Check if restart request is set because of failback event - * happend. If so, exit myself with exit code 1 to be - * restarted by pgpool parent. - */ + /* + * Check if restart request is set because of failback event happend. If + * so, exit myself with exit code 1 to be restarted by pgpool parent. + */ if (pool_get_my_process_info()->need_to_restart) { ereport(LOG, - (errmsg("failback event detected"), + (errmsg("failback event detected"), errdetail("restarting myself"))); pool_get_my_process_info()->need_to_restart = 0; @@ -1679,23 +1730,26 @@ static void check_restart_request(void) static int wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) { - fd_set rmask; - int numfds; - int save_errno; + fd_set rmask; + int numfds; + int save_errno; - int fd = 0; - int afd; - int *walk; - int on; + int fd = 0; + int afd; + int *walk; + int on; #ifdef ACCEPT_PERFORMANCE - struct timeval now1, now2; + struct timeval now1, + now2; static long atime; - static int cnt; + static int cnt; #endif struct timeval *timeoutval; - struct timeval tv1, tv2, tmback = {0, 0}; + struct timeval tv1, + tv2, + tmback = {0, 0}; for (walk = fds; *walk != -1; walk++) pool_set_nonblock(*walk); @@ -1705,8 +1759,8 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) else set_ps_display("wait for connection request", false); - memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set)); - + memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set)); + if (timeout->tv_sec == 0 && timeout->tv_usec == 0) timeoutval = NULL; else @@ -1733,7 +1787,7 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) pool_semaphore_lock(ACCEPT_FD_SEM); set_ps_display("wait for connection request", false); ereport(DEBUG1, - (errmsg("LOCKING select()"))); + (errmsg("LOCKING select()"))); } numfds = select(nsocks, &rmask, NULL, NULL, timeoutval); @@ -1744,7 +1798,7 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) { pool_semaphore_unlock(ACCEPT_FD_SEM); ereport(DEBUG1, - (errmsg("UNLOCKING select()"))); + (errmsg("UNLOCKING select()"))); } /* check backend timer is expired */ @@ -1755,8 +1809,8 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) } /* - * following code fragment computes remaining timeout val in a - * portable way. Linux does this automatically but other platforms do not. + * following code fragment computes remaining timeout val in a portable + * way. Linux does this automatically but other platforms do not. */ if (timeoutval) { @@ -1795,8 +1849,8 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) if (errno == EAGAIN || errno == EINTR) return RETRY; ereport(ERROR, - (errmsg("failed to accept user connection"), - errdetail("select on socket failed with error : \"%s\"",strerror(errno)))); + (errmsg("failed to accept user connection"), + errdetail("select on socket failed with error : \"%s\"", strerror(errno)))); } /* timeout */ @@ -1813,18 +1867,19 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) break; } } + /* - * Note that some SysV systems do not work here. For those - * systems, we need some locking mechanism for the fd. + * Note that some SysV systems do not work here. For those systems, we + * need some locking mechanism for the fd. */ memset(saddr, 0, sizeof(*saddr)); saddr->salen = sizeof(saddr->addr); #ifdef ACCEPT_PERFORMANCE - gettimeofday(&now1,0); + gettimeofday(&now1, 0); #endif - retry_accept: +retry_accept: /* wait if recovery is started */ while (*InRecovery == 1) @@ -1832,8 +1887,8 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) pause(); } - afd = accept(fd, (struct sockaddr *)&saddr->addr, &saddr->salen); - + afd = accept(fd, (struct sockaddr *) &saddr->addr, &saddr->salen); + save_errno = errno; /* check backend timer is expired */ if (backend_timer_expired) @@ -1848,13 +1903,13 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) goto retry_accept; /* - * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) - * can be silently ignored. And EINTR can be ignored. + * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) can be + * silently ignored. And EINTR can be ignored. */ if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) ereport(ERROR, - (errmsg("failed to accept user connection"), - errdetail("accept on socket failed with error : \"%s\"",strerror(errno)))); + (errmsg("failed to accept user connection"), + errdetail("accept on socket failed with error : \"%s\"", strerror(errno)))); return RETRY; } @@ -1871,7 +1926,7 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) sizeof(on)) < 0) { ereport(WARNING, - (errmsg("wait_for_new_connections: setsockopt failed with error \"%s\"",strerror(errno)))); + (errmsg("wait_for_new_connections: setsockopt failed with error \"%s\"", strerror(errno)))); close(afd); return -1; } @@ -1883,25 +1938,27 @@ wait_for_new_connections(int *fds, struct timeval *timeout, SockAddr *saddr) pool_unset_nonblock(afd); #ifdef ACCEPT_PERFORMANCE - gettimeofday(&now2,0); - atime += (now2.tv_sec - now1.tv_sec)*1000000 + (now2.tv_usec - now1.tv_usec); + gettimeofday(&now2, 0); + atime += (now2.tv_sec - now1.tv_sec) * 1000000 + (now2.tv_usec - now1.tv_usec); cnt++; if (cnt % 100 == 0) { - ereport(LOG,(errmsg("cnt: %d atime: %ld", cnt, atime))); + ereport(LOG, (errmsg("cnt: %d atime: %ld", cnt, atime))); } #endif return afd; } -static void check_config_reload(void) +static void +check_config_reload(void) { /* reload config file */ if (got_sighup) { - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); if (pool_config->enable_pool_hba) { load_hba(get_hba_file_name()); @@ -1912,12 +1969,14 @@ static void check_config_reload(void) } } -static void get_backends_status(unsigned int *valid_backends, unsigned int *down_backends) +static void +get_backends_status(unsigned int *valid_backends, unsigned int *down_backends) { - int i; + int i; + *down_backends = 0; - *valid_backends = 0; - for (i=0;i<NUM_BACKENDS;i++) + *valid_backends = 0; + for (i = 0; i < NUM_BACKENDS; i++) { if (BACKEND_INFO(i).backend_status == CON_DOWN) (*down_backends)++; @@ -1926,69 +1985,71 @@ static void get_backends_status(unsigned int *valid_backends, unsigned int *down } } -static void validate_backend_connectivity(int front_end_fd) +static void +validate_backend_connectivity(int front_end_fd) { unsigned int valid_backends; unsigned int down_backends; - bool fatal_error = false; - char *error_msg = NULL; - char *error_detail= NULL; - char *error_hint = NULL; + bool fatal_error = false; + char *error_msg = NULL; + char *error_detail = NULL; + char *error_hint = NULL; - get_backends_status(&valid_backends,&down_backends); + get_backends_status(&valid_backends, &down_backends); - if(valid_backends == 0) + if (valid_backends == 0) { fatal_error = true; error_msg = "pgpool is not accepting any new connections"; error_detail = "all backend nodes are down, pgpool requires at least one valid node"; error_hint = "repair the backend nodes and restart pgpool"; } - - if(fatal_error) + + if (fatal_error) { - /* check if we can inform the connecting client about the current + /* + * check if we can inform the connecting client about the current * situation before throwing the error */ - - if(front_end_fd > 0) + + if (front_end_fd > 0) { POOL_CONNECTION *cp; StartupPacket *sp; - /* - * we do not want to report socket error, as above errors - * will be more informative + /* + * we do not want to report socket error, as above errors will be + * more informative */ PG_TRY(); { - if ((cp = pool_open(front_end_fd,false)) == NULL) + if ((cp = pool_open(front_end_fd, false)) == NULL) { close(front_end_fd); child_exit(POOL_EXIT_AND_RESTART); } sp = read_startup_packet(cp); ereport(DEBUG1, - (errmsg("forwarding error message to frontend"))); - - pool_send_error_message(cp, sp->major, - (sp->major == PROTO_MAJOR_V3)?"08S01":NULL, - error_msg, - error_detail, - error_hint, - __FILE__, - __LINE__); + (errmsg("forwarding error message to frontend"))); + + pool_send_error_message(cp, sp->major, + (sp->major == PROTO_MAJOR_V3) ? "08S01" : NULL, + error_msg, + error_detail, + error_hint, + __FILE__, + __LINE__); } PG_CATCH(); { - FlushErrorState(); + FlushErrorState(); ereport(FATAL, - (errmsg("%s",error_msg),errdetail("%s",error_detail),errhint("%s",error_hint))); + (errmsg("%s", error_msg), errdetail("%s", error_detail), errhint("%s", error_hint))); } PG_END_TRY(); } ereport(FATAL, - (errmsg("%s",error_msg),errdetail("%s",error_detail),errhint("%s",error_hint))); + (errmsg("%s", error_msg), errdetail("%s", error_detail), errhint("%s", error_hint))); } /* Every thing is good if we have reached this point */ } @@ -1997,13 +2058,13 @@ static void validate_backend_connectivity(int front_end_fd) * returns the POOL_CONNECTION object from socket descriptor * the socket must be already accepted */ -static POOL_CONNECTION* +static POOL_CONNECTION * get_connection(int front_end_fd, SockAddr *saddr) { POOL_CONNECTION *cp; ereport(DEBUG1, - (errmsg("I am %d accept fd %d", getpid(), front_end_fd))); + (errmsg("I am %d accept fd %d", getpid(), front_end_fd))); pool_getnameinfo_all(saddr, remote_host, remote_port); print_process_status(remote_host, remote_port); @@ -2014,38 +2075,38 @@ get_connection(int front_end_fd, SockAddr *saddr) if (pool_config->log_connections) { ereport(LOG, - (errmsg("new connection received"), + (errmsg("new connection received"), errdetail("connecting host=%s%s%s", remote_host, remote_port[0] ? " port=" : "", remote_port))); } - + /* set NODELAY and KEEPALIVE options if INET connection */ if (saddr->addr.ss_family == AF_INET || saddr->addr.ss_family == AF_INET6) { - int on = 1; + int on = 1; if (setsockopt(front_end_fd, IPPROTO_TCP, TCP_NODELAY, (char *) &on, sizeof(on)) < 0) ereport(ERROR, - (errmsg("failed to accept user connection"), - errdetail("setsockopt on socket failed with error : \"%s\"",strerror(errno)))); + (errmsg("failed to accept user connection"), + errdetail("setsockopt on socket failed with error : \"%s\"", strerror(errno)))); - if (setsockopt(front_end_fd, SOL_SOCKET, SO_KEEPALIVE,(char *) &on, sizeof(on)) < 0) + if (setsockopt(front_end_fd, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) ereport(FATAL, - (errmsg("failed to accept user connection"), - errdetail("setsockopt on socket failed with error : \"%s\"",strerror(errno)))); + (errmsg("failed to accept user connection"), + errdetail("setsockopt on socket failed with error : \"%s\"", strerror(errno)))); } - if ((cp = pool_open(front_end_fd,false)) == NULL) + if ((cp = pool_open(front_end_fd, false)) == NULL) { close(front_end_fd); - ereport(ERROR, - (errmsg("failed to accept user connection"), - errdetail("unable to open connection with remote end : \"%s\"",strerror(errno)))); + ereport(ERROR, + (errmsg("failed to accept user connection"), + errdetail("unable to open connection with remote end : \"%s\"", strerror(errno)))); } /* save ip address for hba */ @@ -2056,12 +2117,13 @@ get_connection(int front_end_fd, SockAddr *saddr) return cp; } -static POOL_CONNECTION_POOL* - get_backend_connection(POOL_CONNECTION *frontend) +static POOL_CONNECTION_POOL * +get_backend_connection(POOL_CONNECTION * frontend) { - int found = 0; + int found = 0; StartupPacket *sp; POOL_CONNECTION_POOL *backend; + /* read the startup packet */ retry_startup: sp = read_startup_packet(frontend); @@ -2069,7 +2131,7 @@ retry_startup: /* cancel request? */ if (sp->major == 1234 && sp->minor == 5678) { - cancel_request((CancelPacket *)sp->startup_packet); + cancel_request((CancelPacket *) sp->startup_packet); pool_free_startup_packet(sp); return NULL; } @@ -2078,7 +2140,7 @@ retry_startup: if (sp->major == 1234 && sp->minor == 5679 && !frontend->ssl_active) { ereport(DEBUG1, - (errmsg("selecting backend connection"), + (errmsg("selecting backend connection"), errdetail("SSLRequest from client"))); pool_ssl_negotiate_serverclient(frontend); @@ -2093,29 +2155,28 @@ retry_startup: if (pool_config->enable_pool_hba) { /* - * do client authentication. - * Note that ClientAuthentication does not return if frontend - * was rejected; it simply terminates this process. + * do client authentication. Note that ClientAuthentication does not + * return if frontend was rejected; it simply terminates this process. */ ClientAuthentication(frontend); } /* - * Ok, negotiation with frontend has been done. Let's go to the - * next step. Connect to backend if there's no existing - * connection which can be reused by this frontend. - * Authentication is also done in this step. + * Ok, negotiation with frontend has been done. Let's go to the next step. + * Connect to backend if there's no existing connection which can be + * reused by this frontend. Authentication is also done in this step. */ - /* Check if restart request is set because of failback event - * happened. If so, close idle connections to backend and make - * a new copy of backend status. + /* + * Check if restart request is set because of failback event happened. If + * so, close idle connections to backend and make a new copy of backend + * status. */ if (pool_get_my_process_info()->need_to_restart) { ereport(LOG, - (errmsg("selecting backend connection"), + (errmsg("selecting backend connection"), errdetail("failback event detected, discarding existing connections"))); pool_get_my_process_info()->need_to_restart = 0; @@ -2124,42 +2185,46 @@ retry_startup: } /* - * if there's no connection associated with user and database, - * we need to connect to the backend and send the startup packet. + * if there's no connection associated with user and database, we need to + * connect to the backend and send the startup packet. */ /* look for an existing connection */ found = 0; backend = pool_get_cp(sp->user, sp->database, sp->major, 1); - + if (backend != NULL) { found = 1; - /* + + /* * existing connection associated with same user/database/major found. - * however we should make sure that the startup packet contents are identical. - * OPTION data and others might be different. + * however we should make sure that the startup packet contents are + * identical. OPTION data and others might be different. */ if (sp->len != MASTER_CONNECTION(backend)->sp->len) { ereport(DEBUG1, - (errmsg("selecting backend connection"), + (errmsg("selecting backend connection"), errdetail("connection exists but startup packet length is not identical"))); found = 0; } - else if(memcmp(sp->startup_packet, MASTER_CONNECTION(backend)->sp->startup_packet, sp->len) != 0) + else if (memcmp(sp->startup_packet, MASTER_CONNECTION(backend)->sp->startup_packet, sp->len) != 0) { ereport(DEBUG1, - (errmsg("selecting backend connection"), + (errmsg("selecting backend connection"), errdetail("connection exists but startup packet contents is not identical"))); found = 0; } if (found == 0) { - /* we need to discard existing connection since startup packet is different */ + /* + * we need to discard existing connection since startup packet is + * different + */ pool_discard_cp(sp->user, sp->database, sp->major); backend = NULL; } @@ -2181,17 +2246,19 @@ retry_startup: return backend; } -static void print_process_status(char *remote_host,char* remote_port) +static void +print_process_status(char *remote_host, char *remote_port) { - if(remote_port[0] == '\0') - snprintf(remote_ps_data, sizeof(remote_ps_data),"%s",remote_port); + if (remote_port[0] == '\0') + snprintf(remote_ps_data, sizeof(remote_ps_data), "%s", remote_port); else - snprintf(remote_ps_data, sizeof(remote_ps_data),"%s(%s)",remote_host, remote_port); + snprintf(remote_ps_data, sizeof(remote_ps_data), "%s(%s)", remote_host, remote_port); } -bool is_session_connected() +bool +is_session_connected() { - if(processType == PT_CHILD) + if (processType == PT_CHILD) return (pool_get_session_context(true) != NULL); return false; } @@ -2204,14 +2271,15 @@ bool is_session_connected() * primary: primary node * standby: any of standby node * numeric: physical node id - * + * * If specified node does exist, returns MASTER_NODE_ID. If "standby" is * specified, returns -1. Caller should choose one of standby nodes * appropriately. */ -static int choose_db_node_id(char *str) +static int +choose_db_node_id(char *str) { - int node_id = MASTER_NODE_ID; + int node_id = MASTER_NODE_ID; if (!strcmp("primary", str) && PRIMARY_NODE_ID >= 0) { @@ -2223,27 +2291,31 @@ static int choose_db_node_id(char *str) } else { - int tmp = atoi(str); + int tmp = atoi(str); + if (tmp >= 0 && tmp < NUM_BACKENDS) node_id = tmp; } return node_id; } -int send_to_pg_frontend(char* data, int len, bool flush) +int +send_to_pg_frontend(char *data, int len, bool flush) { - int ret; + int ret; + if (processType != PT_CHILD || child_frontend == NULL) return -1; if (child_frontend->socket_state != POOL_SOCKET_VALID) return -1; ret = pool_write_noerror(child_frontend, data, len); - if(flush && !ret) + if (flush && !ret) ret = pool_flush_it(child_frontend); return ret; } -int set_pg_frontend_blocking(bool blocking) +int +set_pg_frontend_blocking(bool blocking) { if (processType != PT_CHILD || child_frontend == NULL) return -1; @@ -2256,14 +2328,16 @@ int set_pg_frontend_blocking(bool blocking) return 0; } -int get_frontend_protocol_version(void) +int +get_frontend_protocol_version(void) { if (processType != PT_CHILD || child_frontend == NULL) return -1; return child_frontend->protoVersion; } -int pg_frontend_exists(void) +int +pg_frontend_exists(void) { if (processType != PT_CHILD || child_frontend == NULL) return -1; diff --git a/src/protocol/pool_connection_pool.c b/src/protocol/pool_connection_pool.c index bb92b8346..d5f05a5ab 100644 --- a/src/protocol/pool_connection_pool.c +++ b/src/protocol/pool_connection_pool.c @@ -50,59 +50,64 @@ #include "utils/memutils.h" #include "context/pool_process_context.h" -static int pool_index; /* Active pool index */ -POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ -volatile sig_atomic_t backend_timer_expired = 0; /* flag for connection closed timer is expired */ -volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check timer expired */ -static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot); -static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p); -static int check_socket_status(int fd); +static int pool_index; /* Active pool index */ +POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ +volatile sig_atomic_t backend_timer_expired = 0; /* flag for connection + * closed timer is expired */ +volatile sig_atomic_t health_check_timer_expired; /* non 0 if health check + * timer expired */ +static POOL_CONNECTION_POOL_SLOT * create_cp(POOL_CONNECTION_POOL_SLOT * cp, int slot); +static POOL_CONNECTION_POOL * new_connection(POOL_CONNECTION_POOL * p); +static int check_socket_status(int fd); static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int port, bool retry); /* * initialize connection pools. this should be called once at the startup. */ -int pool_init_cp(void) +int +pool_init_cp(void) { - int i; + int i; MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); - pool_connection_pool = (POOL_CONNECTION_POOL *)palloc(sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool); - memset(pool_connection_pool, 0, sizeof(POOL_CONNECTION_POOL)*pool_config->max_pool); + pool_connection_pool = (POOL_CONNECTION_POOL *) palloc(sizeof(POOL_CONNECTION_POOL) * pool_config->max_pool); + memset(pool_connection_pool, 0, sizeof(POOL_CONNECTION_POOL) * pool_config->max_pool); for (i = 0; i < pool_config->max_pool; i++) { pool_connection_pool[i].info = pool_coninfo(pool_get_process_context()->proc_id, i, 0); memset(pool_connection_pool[i].info, 0, sizeof(ConnectionInfo) * MAX_NUM_BACKENDS); } - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); return 0; } /* * find connection by user and database */ -POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, int check_socket) +POOL_CONNECTION_POOL * +pool_get_cp(char *user, char *database, int protoMajor, int check_socket) { pool_sigset_t oldmask; - int i, freed = 0; + int i, + freed = 0; ConnectionInfo *info; POOL_CONNECTION_POOL *connection_pool = pool_connection_pool; if (connection_pool == NULL) { - /* if no connection pool exists we have no reason to live */ - ereport(ERROR, - (return_code(2), - errmsg("unable to get connection"), - errdetail("connection pool is not initialized"))); + /* if no connection pool exists we have no reason to live */ + ereport(ERROR, + (return_code(2), + errmsg("unable to get connection"), + errdetail("connection pool is not initialized"))); } POOL_SETMASK2(&BlockSig, &oldmask); - for (i=0;i<pool_config->max_pool;i++) + for (i = 0; i < pool_config->max_pool; i++) { if (MASTER_CONNECTION(connection_pool) && MASTER_CONNECTION(connection_pool)->sp && @@ -111,12 +116,12 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in strcmp(MASTER_CONNECTION(connection_pool)->sp->user, user) == 0 && strcmp(MASTER_CONNECTION(connection_pool)->sp->database, database) == 0) { - int sock_broken = 0; - int j; + int sock_broken = 0; + int j; /* mark this connection is under use */ MASTER_CONNECTION(connection_pool)->closetime = 0; - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { connection_pool->info[j].counter++; } @@ -124,12 +129,12 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in if (check_socket) { - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (!VALID_BACKEND(j)) continue; - if (CONNECTION_SLOT(connection_pool, j)) + if (CONNECTION_SLOT(connection_pool, j)) { sock_broken = check_socket_status(CONNECTION(connection_pool, j)->fd); if (sock_broken < 0) @@ -145,10 +150,10 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in if (sock_broken < 0) { ereport(LOG, - (errmsg("connection closed."), + (errmsg("connection closed."), errdetail("retry to create new connection pool"))); - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (!VALID_BACKEND(j) || (CONNECTION_SLOT(connection_pool, j) == NULL)) continue; @@ -156,7 +161,7 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in if (!freed) { pool_free_startup_packet(CONNECTION_SLOT(connection_pool, j)->sp); - CONNECTION_SLOT(connection_pool, j)->sp = NULL; + CONNECTION_SLOT(connection_pool, j)->sp = NULL; freed = 1; } @@ -187,20 +192,22 @@ POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor, in /* * disconnect and release a connection to the database */ -void pool_discard_cp(char *user, char *database, int protoMajor) +void +pool_discard_cp(char *user, char *database, int protoMajor) { POOL_CONNECTION_POOL *p = pool_get_cp(user, database, protoMajor, 0); ConnectionInfo *info; - int i, freed = 0; + int i, + freed = 0; if (p == NULL) { ereport(LOG, - (errmsg("cannot get connection pool for user: \"%s\" database: \"%s\", while discarding connection pool", user, database))); + (errmsg("cannot get connection pool for user: \"%s\" database: \"%s\", while discarding connection pool", user, database))); return; } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -210,7 +217,7 @@ void pool_discard_cp(char *user, char *database, int protoMajor) pool_free_startup_packet(CONNECTION_SLOT(p, i)->sp); freed = 1; } - CONNECTION_SLOT(p, i)->sp = NULL; + CONNECTION_SLOT(p, i)->sp = NULL; pool_close(CONNECTION(p, i)); pfree(CONNECTION_SLOT(p, i)); } @@ -225,23 +232,26 @@ void pool_discard_cp(char *user, char *database, int protoMajor) /* * create a connection pool by user and database */ -POOL_CONNECTION_POOL *pool_create_cp(void) +POOL_CONNECTION_POOL * +pool_create_cp(void) { - int i, freed = 0; - time_t closetime; + int i, + freed = 0; + time_t closetime; POOL_CONNECTION_POOL *oldestp; POOL_CONNECTION_POOL *ret; ConnectionInfo *info; POOL_CONNECTION_POOL *p = pool_connection_pool; - /* if no connection pool exists we have no reason to live */ + + /* if no connection pool exists we have no reason to live */ if (p == NULL) - ereport(ERROR, - (return_code(2), + ereport(ERROR, + (return_code(2), errmsg("unable to create connection"), - errdetail("connection pool is not initialized"))); + errdetail("connection pool is not initialized"))); - for (i=0;i<pool_config->max_pool;i++) + for (i = 0; i < pool_config->max_pool; i++) { if (MASTER_CONNECTION(p) == NULL) { @@ -253,24 +263,25 @@ POOL_CONNECTION_POOL *pool_create_cp(void) p++; } ereport(DEBUG1, - (errmsg("creating connection pool"), + (errmsg("creating connection pool"), errdetail("no empty connection slot was found"))); /* - * no empty connection slot was found. look for the oldest connection and discard it. + * no empty connection slot was found. look for the oldest connection and + * discard it. */ oldestp = p = pool_connection_pool; closetime = MASTER_CONNECTION(p)->closetime; pool_index = 0; - for (i=0;i<pool_config->max_pool;i++) + for (i = 0; i < pool_config->max_pool; i++) { ereport(DEBUG1, - (errmsg("creating connection pool"), - errdetail("user: %s database: %s closetime: %ld", - MASTER_CONNECTION(p)->sp->user, - MASTER_CONNECTION(p)->sp->database, - MASTER_CONNECTION(p)->closetime))); + (errmsg("creating connection pool"), + errdetail("user: %s database: %s closetime: %ld", + MASTER_CONNECTION(p)->sp->user, + MASTER_CONNECTION(p)->sp->database, + MASTER_CONNECTION(p)->closetime))); if (MASTER_CONNECTION(p)->closetime < closetime) { @@ -285,13 +296,13 @@ POOL_CONNECTION_POOL *pool_create_cp(void) pool_send_frontend_exits(p); ereport(DEBUG1, - (errmsg("creating connection pool"), - errdetail("discarding old %zd th connection. user: %s database: %s", - oldestp - pool_connection_pool, - MASTER_CONNECTION(p)->sp->user, - MASTER_CONNECTION(p)->sp->database))); + (errmsg("creating connection pool"), + errdetail("discarding old %zd th connection. user: %s database: %s", + oldestp - pool_connection_pool, + MASTER_CONNECTION(p)->sp->user, + MASTER_CONNECTION(p)->sp->database))); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -299,7 +310,7 @@ POOL_CONNECTION_POOL *pool_create_cp(void) if (!freed) { pool_free_startup_packet(CONNECTION_SLOT(p, i)->sp); - CONNECTION_SLOT(p, i)->sp = NULL; + CONNECTION_SLOT(p, i)->sp = NULL; freed = 1; } @@ -320,22 +331,24 @@ POOL_CONNECTION_POOL *pool_create_cp(void) /* * set backend connection close timer */ -void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend) +void +pool_connection_pool_timer(POOL_CONNECTION_POOL * backend) { POOL_CONNECTION_POOL *p = pool_connection_pool; - int i; + int i; ereport(DEBUG1, - (errmsg("setting backend connection close timer"), + (errmsg("setting backend connection close timer"), errdetail("close time %ld", time(NULL)))); - MASTER_CONNECTION(backend)->closetime = time(NULL); /* set connection close time */ + MASTER_CONNECTION(backend)->closetime = time(NULL); /* set connection close + * time */ if (pool_config->connection_life_time == 0) return; /* look for any other timeout */ - for (i=0;i<pool_config->max_pool;i++, p++) + for (i = 0; i < pool_config->max_pool; i++, p++) { if (!MASTER_CONNECTION(p)) continue; @@ -350,7 +363,7 @@ void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend) /* no other timer found. set my timer */ ereport(DEBUG1, - (errmsg("setting backend connection close timer"), + (errmsg("setting backend connection close timer"), errdetail("setting alarm after %d seconds", pool_config->connection_life_time))); pool_alarm(pool_backend_timer_handler, pool_config->connection_life_time); @@ -359,19 +372,22 @@ void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend) /* * backend connection close timer handler */ -RETSIGTYPE pool_backend_timer_handler(int sig) +RETSIGTYPE +pool_backend_timer_handler(int sig) { backend_timer_expired = 1; } -void pool_backend_timer(void) +void +pool_backend_timer(void) { #define TMINTMAX 0x7fffffff POOL_CONNECTION_POOL *p = pool_connection_pool; - int i, j; - time_t now; - time_t nearest = TMINTMAX; + int i, + j; + time_t now; + time_t nearest = TMINTMAX; ConnectionInfo *info; POOL_SETMASK(&BlockSig); @@ -379,9 +395,9 @@ void pool_backend_timer(void) now = time(NULL); ereport(DEBUG1, - (errmsg("backend timer handler called at%ld", now))); + (errmsg("backend timer handler called at%ld", now))); - for (i=0;i<pool_config->max_pool;i++, p++) + for (i = 0; i < pool_config->max_pool; i++, p++) { if (!MASTER_CONNECTION(p)) continue; @@ -393,23 +409,23 @@ void pool_backend_timer(void) /* timer expire? */ if (MASTER_CONNECTION(p)->closetime) { - int freed = 0; + int freed = 0; ereport(DEBUG1, - (errmsg("backend timer handler called"), - errdetail("expire time: %ld", - MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time))); + (errmsg("backend timer handler called"), + errdetail("expire time: %ld", + MASTER_CONNECTION(p)->closetime + pool_config->connection_life_time))); - if (now >= (MASTER_CONNECTION(p)->closetime+pool_config->connection_life_time)) + if (now >= (MASTER_CONNECTION(p)->closetime + pool_config->connection_life_time)) { /* discard expired connection */ ereport(DEBUG1, - (errmsg("backend timer handler called"), - errdetail("expired user: \"%s\" database: \"%s\"", - MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database))); + (errmsg("backend timer handler called"), + errdetail("expired user: \"%s\" database: \"%s\"", + MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database))); pool_send_frontend_exits(p); - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (!VALID_BACKEND(j)) continue; @@ -419,7 +435,7 @@ void pool_backend_timer(void) pool_free_startup_packet(CONNECTION_SLOT(p, j)->sp); freed = 1; } - CONNECTION_SLOT(p, j)->sp = NULL; + CONNECTION_SLOT(p, j)->sp = NULL; pool_close(CONNECTION(p, j)); pfree(CONNECTION_SLOT(p, j)); } @@ -442,7 +458,7 @@ void pool_backend_timer(void) { nearest = pool_config->connection_life_time - (now - nearest); if (nearest <= 0) - nearest = 1; + nearest = 1; pool_alarm(pool_backend_timer_handler, nearest); } @@ -452,10 +468,11 @@ void pool_backend_timer(void) /* * connect to postmaster through INET domain socket */ -int connect_inet_domain_socket(int slot, bool retry) +int +connect_inet_domain_socket(int slot, bool retry) { - char *host; - int port; + char *host; + int port; host = pool_config->backend_desc->backend_info[slot].backend_hostname; port = pool_config->backend_desc->backend_info[slot].backend_port; @@ -466,10 +483,11 @@ int connect_inet_domain_socket(int slot, bool retry) /* * connect to postmaster through UNIX domain socket */ -int connect_unix_domain_socket(int slot, bool retry) +int +connect_unix_domain_socket(int slot, bool retry) { - int port; - char *socket_dir; + int port; + char *socket_dir; port = pool_config->backend_desc->backend_info[slot].backend_port; socket_dir = pool_config->backend_desc->backend_info[slot].backend_hostname; @@ -481,17 +499,18 @@ int connect_unix_domain_socket(int slot, bool retry) * Connect to PostgreSQL server by using UNIX domain socket. * If retry is true, retry to call connect() upon receiving EINTR error. */ -int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry) +int +connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry) { struct sockaddr_un addr; - int fd; - int len; + int fd; + int len; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server by unix domain socket"), + (errmsg("failed to connect to PostgreSQL server by unix domain socket"), errdetail("create socket failed with error \"%s\"", strerror(errno)))); return -1; } @@ -506,20 +525,20 @@ int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry) if (exit_request) /* exit request already sent */ { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server by unix domain socket"), + (errmsg("failed to connect to PostgreSQL server by unix domain socket"), errdetail("exit request has been sent"))); close(fd); return -1; } - if (connect(fd, (struct sockaddr *)&addr, len) < 0) + if (connect(fd, (struct sockaddr *) &addr, len) < 0) { if ((errno == EINTR && retry) || errno == EAGAIN) continue; close(fd); ereport(LOG, - (errmsg("failed to connect to PostgreSQL server by unix domain socket"), - errdetail("connect to \"%s\" failed with error \"%s\"",addr.sun_path, strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server by unix domain socket"), + errdetail("connect to \"%s\" failed with error \"%s\"", addr.sun_path, strerror(errno)))); return -1; } @@ -538,14 +557,16 @@ int connect_unix_domain_socket_by_port(int port, char *socket_dir, bool retry) * purpose. * retry: true if need to retry */ -static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int port, bool retry) +static bool +connect_with_timeout(int fd, struct addrinfo *walk, char *host, int port, bool retry) { struct timeval *tm; struct timeval timeout; - fd_set rset, wset; - int sts; - int error; - socklen_t socklen; + fd_set rset, + wset; + int sts; + int error; + socklen_t socklen; pool_set_nonblock(fd); @@ -554,16 +575,16 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int if (exit_request) /* exit request already sent */ { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket",host,port), + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket", host, port), errdetail("exit request has been sent"))); close(fd); return false; } - if (health_check_timer_expired) /* has health check timer expired */ + if (health_check_timer_expired) /* has health check timer expired */ { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket",host,port), + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket", host, port), errdetail("health check timer expired"))); close(fd); return false; @@ -587,7 +608,7 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int if (errno != EINPROGRESS && errno != EALREADY) { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" with error \"%s\"",host,port,strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" with error \"%s\"", host, port, strerror(errno)))); return false; } @@ -596,22 +617,22 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int else { tm = &timeout; - timeout.tv_sec = pool_config->connect_timeout/1000; + timeout.tv_sec = pool_config->connect_timeout / 1000; if (timeout.tv_sec == 0) { - timeout.tv_usec = pool_config->connect_timeout*1000; + timeout.tv_usec = pool_config->connect_timeout * 1000; } else { - timeout.tv_usec = (pool_config->connect_timeout - timeout.tv_sec*1000)*1000; + timeout.tv_usec = (pool_config->connect_timeout - timeout.tv_sec * 1000) * 1000; } } FD_ZERO(&rset); - FD_SET(fd, &rset); + FD_SET(fd, &rset); FD_ZERO(&wset); FD_SET(fd, &wset); - sts = select(fd+1, &rset, &wset, NULL, tm); + sts = select(fd + 1, &rset, &wset, NULL, tm); if (sts == 0) { @@ -619,14 +640,14 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int if (retry) { ereport(LOG, - (errmsg("trying connecting to PostgreSQL server on \"%s:%d\" by INET socket",host,port), + (errmsg("trying connecting to PostgreSQL server on \"%s:%d\" by INET socket", host, port), errdetail("timed out. retrying..."))); continue; } else { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", timed out",host,port))); + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", timed out", host, port))); return false; } } @@ -634,11 +655,10 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int { /* * If read data or write data was set, either connect - * succeeded or error. We need to figure it out. This - * is the hardest part in using non blocking - * connect(2). See W. Richar Stevens's "UNIX Network - * Programming: Volume 1, Second Edition" section - * 15.4. + * succeeded or error. We need to figure it out. This is the + * hardest part in using non blocking connect(2). See W. + * Richar Stevens's "UNIX Network Programming: Volume 1, + * Second Edition" section 15.4. */ if (FD_ISSET(fd, &rset) || FD_ISSET(fd, &wset)) { @@ -648,7 +668,7 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int { /* Solaris returns error in this case */ ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", getsockopt() failed with error \"%s\"",host,port,strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", getsockopt() failed with error \"%s\"", host, port, strerror(errno)))); return false; } @@ -657,24 +677,24 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int if (error != 0) { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", getsockopt() detected error \"%s\"",host,port,strerror(error)))); + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", getsockopt() detected error \"%s\"", host, port, strerror(error)))); return false; } } else { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", both read data and write data was not set",host,port))); + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\", both read data and write data was not set", host, port))); return false; } } - else /* select returns error */ + else /* select returns error */ { if ((errno == EINTR && retry) || errno == EAGAIN) { ereport(LOG, - (errmsg("trying to connect to PostgreSQL server on \"%s:%d\" using INET socket",host,port), + (errmsg("trying to connect to PostgreSQL server on \"%s:%d\" using INET socket", host, port), errdetail("select() interrupted. retrying..."))); continue; } @@ -697,14 +717,14 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int else if (health_check_timer_expired && errno == EINTR) { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket",host,port), + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket", host, port), errdetail("health check timer expired"))); } else { ereport(LOG, - (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket",host,port), - errdetail("select() system call failed with an error \"%s\"",strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server on \"%s:%d\" using INET socket", host, port), + errdetail("select() system call failed with an error \"%s\"", strerror(errno)))); } close(fd); return false; @@ -721,21 +741,25 @@ static bool connect_with_timeout(int fd, struct addrinfo *walk, char *host, int * Connect to PostgreSQL server by using INET domain socket. * If retry is true, retry to call connect() upon receiving EINTR error. */ -int connect_inet_domain_socket_by_port(char *host, int port, bool retry) +int +connect_inet_domain_socket_by_port(char *host, int port, bool retry) { - int fd = -1; - int on = 1; - char *portstr; - int ret; + int fd = -1; + int on = 1; + char *portstr; + int ret; struct addrinfo *res; struct addrinfo *walk; struct addrinfo hints; - /* getaddrinfo() requires a string because it also accepts service names, such as "http". */ + /* + * getaddrinfo() requires a string because it also accepts service names, + * such as "http". + */ if (asprintf(&portstr, "%d", port) == -1) { ereport(WARNING, - (errmsg("failed to connect to PostgreSQL server, asprintf() failed with error \"%s\"",strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server, asprintf() failed with error \"%s\"", strerror(errno)))); return -1; } @@ -747,7 +771,7 @@ int connect_inet_domain_socket_by_port(char *host, int port, bool retry) if ((ret = getaddrinfo(host, portstr, &hints, &res)) != 0) { ereport(WARNING, - (errmsg("failed to connect to PostgreSQL server, getaddrinfo() failed with error \"%s\"",gai_strerror(ret)))); + (errmsg("failed to connect to PostgreSQL server, getaddrinfo() failed with error \"%s\"", gai_strerror(ret)))); free(portstr); return -1; @@ -761,7 +785,7 @@ int connect_inet_domain_socket_by_port(char *host, int port, bool retry) if (fd < 0) { ereport(WARNING, - (errmsg("failed to connect to PostgreSQL server, socket() failed with error \"%s\"",strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server, socket() failed with error \"%s\"", strerror(errno)))); continue; } @@ -771,7 +795,7 @@ int connect_inet_domain_socket_by_port(char *host, int port, bool retry) sizeof(on)) < 0) { ereport(WARNING, - (errmsg("failed to connect to PostgreSQL server, setsockopt() failed with error \"%s\"",strerror(errno)))); + (errmsg("failed to connect to PostgreSQL server, setsockopt() failed with error \"%s\"", strerror(errno)))); close(fd); freeaddrinfo(res); @@ -791,14 +815,14 @@ int connect_inet_domain_socket_by_port(char *host, int port, bool retry) freeaddrinfo(res); return -1; } - + /* * create connection pool */ -static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int slot) +static POOL_CONNECTION_POOL_SLOT * create_cp(POOL_CONNECTION_POOL_SLOT * cp, int slot) { BackendInfo *b = &pool_config->backend_desc->backend_info[slot]; - int fd; + int fd; if (*b->backend_hostname == '/') { @@ -813,7 +837,7 @@ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int s return NULL; cp->sp = NULL; - cp->con = pool_open(fd,true); + cp->con = pool_open(fd, true); cp->closetime = 0; return cp; } @@ -822,26 +846,26 @@ static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int s * Create actual connections to backends. * New connection resides in TopMemoryContext. */ -static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) +static POOL_CONNECTION_POOL * new_connection(POOL_CONNECTION_POOL * p) { POOL_CONNECTION_POOL_SLOT *s; - int active_backend_count = 0; - int i; + int active_backend_count = 0; + int i; + + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); - - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { ereport(DEBUG1, - (errmsg("creating new connection to backend"), + (errmsg("creating new connection to backend"), errdetail("connecting %d backend", i))); if (!VALID_BACKEND(i)) { ereport(DEBUG1, - (errmsg("creating new connection to backend"), - errdetail("skipping backend slot %d because backend_status = %d", - i, BACKEND_INFO(i).backend_status))); + (errmsg("creating new connection to backend"), + errdetail("skipping backend slot %d because backend_status = %d", + i, BACKEND_INFO(i).backend_status))); continue; } @@ -856,8 +880,8 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) { ereport(DEBUG1, (errmsg("creating new connection to backend"), - errdetail("skipping backend slot %d because global backend_status = %d", - i, BACKEND_INFO(i).backend_status))); + errdetail("skipping backend slot %d because global backend_status = %d", + i, BACKEND_INFO(i).backend_status))); continue; } @@ -865,14 +889,15 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) if (create_cp(s, i) == NULL) { - /* If fail_over_on_backend_error is true, do failover. - * Otherwise, just exit this session or skip next health node. + /* + * If fail_over_on_backend_error is true, do failover. Otherwise, + * just exit this session or skip next health node. */ if (pool_config->fail_over_on_backend_error) { notice_backend_error(i, REQ_DETAIL_SWITCHOVER); ereport(FATAL, - (errmsg("failed to create a backend connection"), + (errmsg("failed to create a backend connection"), errdetail("executing failover on backend"))); } else @@ -893,7 +918,8 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) /* if master_node_id is not updated, the update it */ if (Req_info->master_node_id == i) { - int old_master = Req_info->master_node_id; + int old_master = Req_info->master_node_id; + Req_info->master_node_id = get_next_master_node(); ereport(LOG, @@ -901,7 +927,8 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) old_master, Req_info->master_node_id))); } - /* make sure that we need to restart the process after + /* + * make sure that we need to restart the process after * finishing this session */ pool_get_my_process_info()->need_to_restart = 1; @@ -921,7 +948,7 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) p->slots[i] = s; pool_init_params(&s->con->params); - + if (BACKEND_INFO(i).backend_status != CON_UP) { BACKEND_INFO(i).backend_status = CON_UP; @@ -930,9 +957,9 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) active_backend_count++; } - (void)write_status_file(); + (void) write_status_file(); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); if (active_backend_count > 0) { @@ -946,10 +973,11 @@ static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) * RETURN: 0 => OK * -1 => broken socket. */ -static int check_socket_status(int fd) +static int +check_socket_status(int fd) { - fd_set rfds; - int result; + fd_set rfds; + int result; struct timeval t; for (;;) @@ -959,7 +987,7 @@ static int check_socket_status(int fd) t.tv_sec = t.tv_usec = 0; - result = select(fd+1, &rfds, NULL, NULL, &t); + result = select(fd + 1, &rfds, NULL, NULL, &t); if (result < 0 && errno == EINTR) { continue; @@ -976,7 +1004,8 @@ static int check_socket_status(int fd) /* * Return current used index (i.e. frontend connected) */ -int pool_pool_index(void) +int +pool_pool_index(void) { return pool_index; } diff --git a/src/protocol/pool_process_query.c b/src/protocol/pool_process_query.c index 835716f53..106cb23e4 100644 --- a/src/protocol/pool_process_query.c +++ b/src/protocol/pool_process_query.c @@ -62,57 +62,61 @@ #define FD_SETSIZE 512 #endif -#define ACTIVE_SQL_TRANSACTION_ERROR_CODE "25001" /* SET TRANSACTION ISOLATION LEVEL must be called before any query */ +#define ACTIVE_SQL_TRANSACTION_ERROR_CODE "25001" /* SET TRANSACTION + * ISOLATION LEVEL must be + * called before any query */ #define DEADLOCK_ERROR_CODE "40P01" #define SERIALIZATION_FAIL_ERROR_CODE "40001" #define QUERY_CANCEL_ERROR_CODE "57014" #define ADMIN_SHUTDOWN_ERROR_CODE "57P01" #define CRASH_SHUTDOWN_ERROR_CODE "57P02" -static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt); +static int reset_backend(POOL_CONNECTION_POOL * backend, int qcnt); static char *get_insert_command_table_name(InsertStmt *node); -static bool is_cache_empty(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static bool is_cache_empty(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend); static bool is_panic_or_fatal_error(const char *message, int major); -static int detect_error(POOL_CONNECTION *master, char *error_code, int major, char class, bool unread); -static int detect_postmaster_down_error(POOL_CONNECTION *master, int major); +static int detect_error(POOL_CONNECTION * master, char *error_code, int major, char class, bool unread); +static int detect_postmaster_down_error(POOL_CONNECTION * master, int major); static bool is_internal_transaction_needed(Node *node); static bool pool_has_insert_lock(void); -static POOL_STATUS add_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char* table); -static bool has_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char* table, bool for_update); -static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char* table); -static POOL_STATUS read_packets_and_process(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int reset_request, int *state, short *num_fields, bool *cont); +static POOL_STATUS add_lock_target(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *table); +static bool has_lock_target(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *table, bool for_update); +static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *table); +static POOL_STATUS read_packets_and_process(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int reset_request, int *state, short *num_fields, bool *cont); static bool is_all_slaves_command_complete(unsigned char *kind_list, int num_backends, int master); -static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int backend_idx, char kind); +static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int backend_idx, char kind); + /* timeout sec for pool_check_fd */ -static int timeoutsec = -1; +static int timeoutsec = -1; /* * Main module for query processing * reset_request: if non 0, call reset_backend to execute reset queries */ -POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - int reset_request) +POOL_STATUS +pool_process_query(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + int reset_request) { - short num_fields = 0; /* the number of fields in a row (V2 protocol) */ + short num_fields = 0; /* the number of fields in a row (V2 protocol) */ POOL_STATUS status; - int qcnt; - int i; + int qcnt; + int i; MemoryContext ProcessQueryContext = AllocSetContextCreate(QueryContext, - "pool_process_query", - ALLOCSET_DEFAULT_MINSIZE, - ALLOCSET_DEFAULT_INITSIZE, - ALLOCSET_DEFAULT_MAXSIZE); + "pool_process_query", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); /* * This variable is used while processing reset_request (i.e.: - * reset_request == 1). If state is 0, then we call - * reset_backend. And we set state to 1 so that we wait for ready - * for query message from badckends. + * reset_request == 1). If state is 0, then we call reset_backend. And we + * set state to 1 so that we wait for ready for query message from + * badckends. */ - int state; + int state; - frontend->no_forward = reset_request; + frontend->no_forward = reset_request; qcnt = 0; state = 0; @@ -132,20 +136,24 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, /* Are we requested to send reset queries? */ if (state == 0 && reset_request) { - int st; + int st; - /* send query for resetting connection such as "ROLLBACK" "RESET ALL"... */ + /* + * send query for resetting connection such as "ROLLBACK" "RESET + * ALL"... + */ st = reset_backend(backend, qcnt); - if (st < 0) /* error? */ + if (st < 0) /* error? */ { - /* probably we don't need this, since caller will - * close the connection to frontend after returning with POOL_END. But I + /* + * probably we don't need this, since caller will close the + * connection to frontend after returning with POOL_END. But I * guess I would like to be a paranoid... */ frontend->no_forward = 0; - ereport(ERROR, - (errmsg("unable to reset backend status"))); + ereport(ERROR, + (errmsg("unable to reset backend status"))); } else if (st == 0) /* no query issued? */ @@ -161,9 +169,9 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, continue; } - else /* no more query(st == 2) */ + else /* no more query(st == 2) */ { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) TSTATE(backend, i) = 'I'; @@ -181,21 +189,22 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, */ if (*InRecovery > RECOVERY_INIT && pool_config->client_idle_limit_in_recovery == -1) { - ereport(ERROR, - (pool_error_code("57000"), - errmsg("connection terminated due to online recovery"), - errdetail("child connection forced to terminate due to client_idle_limit_in_recovery = -1"))); + ereport(ERROR, + (pool_error_code("57000"), + errmsg("connection terminated due to online recovery"), + errdetail("child connection forced to terminate due to client_idle_limit_in_recovery = -1"))); } /* - * If we are not processing a query, now is the time to - * extract pending data from buffer stack if any. + * If we are not processing a query, now is the time to extract + * pending data from buffer stack if any. */ if (!pool_is_query_in_progress()) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { - int plen; + int plen; + if (VALID_BACKEND(i) && pool_stacklen(CONNECTION(backend, i)) > 0) pool_pop(CONNECTION(backend, i), &plen); } @@ -214,13 +223,14 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, } /* - * If frontend and all backends do not have any pending data in - * the receiving data cache, then issue select(2) to wait for new - * data arrival + * If frontend and all backends do not have any pending data in the + * receiving data cache, then issue select(2) to wait for new data + * arrival */ else if (is_cache_empty(frontend, backend)) { - bool cont = true; + bool cont = true; + status = read_packets_and_process(frontend, backend, reset_request, &state, &num_fields, &cont); if (status != POOL_CONTINUE) return status; @@ -232,12 +242,14 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, if ((pool_ssl_pending(frontend) || !pool_read_buffer_is_empty(frontend)) && !pool_is_query_in_progress()) { - /* We do not read anything from frontend after receiving X packet. - * Just emit log message. This will guard us from buggy frontend. + /* + * We do not read anything from frontend after receiving X + * packet. Just emit log message. This will guard us from + * buggy frontend. */ if (reset_request) { - elog(LOG,"garbage data from frontend after receiving terminate message ignored"); + elog(LOG, "garbage data from frontend after receiving terminate message ignored"); pool_discard_read_buffer(frontend); } else @@ -249,9 +261,8 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, } /* - * ProcessFrontendResponse() may start query - * processing. We need to re-check - * pool_is_query_in_progress() here. + * ProcessFrontendResponse() may start query processing. We need + * to re-check pool_is_query_in_progress() here. */ if (pool_is_query_in_progress()) { @@ -261,24 +272,28 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, } else { - /* Ok, query is not in progress. - * ProcessFrontendResponse() may consume all pending - * data. Check if we have any pending data. If not, - * call read_packets_and_process() and wait for data - * arrival. + /* + * Ok, query is not in progress. ProcessFrontendResponse() may + * consume all pending data. Check if we have any pending + * data. If not, call read_packets_and_process() and wait for + * data arrival. */ if (is_cache_empty(frontend, backend)) { - bool cont = true; + bool cont = true; + status = read_packets_and_process(frontend, backend, reset_request, &state, &num_fields, &cont); if (status != POOL_CONTINUE) return status; - else if (!cont) /* Detected admin shutdown */ + else if (!cont) /* Detected admin shutdown */ return status; } else { - /* If we have pending data in master, we need to process it */ + /* + * If we have pending data in master, we need to process + * it + */ if (pool_ssl_pending(MASTER(backend)) || !pool_read_buffer_is_empty(MASTER(backend))) { @@ -288,7 +303,7 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, } else { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -296,7 +311,10 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, if (pool_ssl_pending(CONNECTION(backend, i)) || !pool_read_buffer_is_empty(CONNECTION(backend, i))) { - /* If we have pending data in master, we need to process it */ + /* + * If we have pending data in master, we need + * to process it + */ if (IS_MASTER_NODE_ID(i)) { status = ProcessBackendResponse(frontend, backend, &state, &num_fields); @@ -306,61 +324,76 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, } else { - char kind; - int len; - char *string; - - /* If master does not have pending - * data, we discard one packet from - * other backend */ + char kind; + int len; + char *string; + + /* + * If master does not have pending data, + * we discard one packet from other + * backend + */ pool_read_with_error(CONNECTION(backend, i), &kind, sizeof(kind), - "reading message kind from backend"); + "reading message kind from backend"); if (kind == 'A') { if (MASTER_SLAVE) { - int sendlen; + int sendlen; + /* - * In master slave mode we may send the query to the standby - * node and the NOTIFY comes back only from primary node. But since - * we have sent the query to the standby, so the current MASTER_NODE_ID - * will be pointing to the standby node. And we will get stuck if we - * keep waiting for the current master node (standby) in this case to - * send us the NOTIFY message. - * see "0000116: LISTEN Notifications Not Reliably Delivered Using JDBC4 Demonstrator" - * for the scenario + * In master slave mode we may + * send the query to the standby + * node and the NOTIFY comes back + * only from primary node. But + * since we have sent the query to + * the standby, so the current + * MASTER_NODE_ID will be pointing + * to the standby node. And we + * will get stuck if we keep + * waiting for the current master + * node (standby) in this case to + * send us the NOTIFY message. see + * "0000116: LISTEN Notifications + * Not Reliably Delivered Using + * JDBC4 Demonstrator" for the + * scenario */ pool_read_with_error(CONNECTION(backend, i), &len, sizeof(len), "reading message length from backend"); len = ntohl(len) - 4; - string = pool_read2(CONNECTION(backend,i), len); + string = pool_read2(CONNECTION(backend, i), len); if (string == NULL) ereport(ERROR, - (errmsg("unable to forward NOTIFY message to frontend"), + (errmsg("unable to forward NOTIFY message to frontend"), errdetail("read from backend failed"))); pool_write(frontend, &kind, 1); - sendlen = htonl(len+4); + sendlen = htonl(len + 4); pool_write(frontend, &sendlen, sizeof(sendlen)); pool_write_and_flush(frontend, string, len); } else { /* - * In replication mode, NOTIFY is sent to all backends. - * However the order of arrival of 'Notification response' - * is not necessarily the master first and then slaves. - * So if it arrives slave first, we should try to read from master, - * rather than just discard it. + * In replication mode, NOTIFY is + * sent to all backends. However + * the order of arrival of + * 'Notification response' is not + * necessarily the master first + * and then slaves. So if it + * arrives slave first, we should + * try to read from master, rather + * than just discard it. */ pool_unread(CONNECTION(backend, i), &kind, sizeof(kind)); ereport(LOG, - (errmsg("pool process query"), + (errmsg("pool process query"), errdetail("received %c packet from backend %d. Don't dicard and read %c packet from master", kind, i, kind))); pool_read_with_error(CONNECTION(backend, MASTER_NODE_ID), &kind, sizeof(kind), - "reading message kind from backend"); + "reading message kind from backend"); pool_unread(CONNECTION(backend, MASTER_NODE_ID), &kind, sizeof(kind)); } @@ -372,31 +405,31 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, else if (!SL_MODE) { - ereport(LOG, - (errmsg("pool process query"), - errdetail("discard %c packet from backend %d", kind, i))); + ereport(LOG, + (errmsg("pool process query"), + errdetail("discard %c packet from backend %d", kind, i))); if (MAJOR(backend) == PROTO_MAJOR_V3) { pool_read_with_error(CONNECTION(backend, i), &len, sizeof(len), - "reading message length from backend"); + "reading message length from backend"); len = ntohl(len) - 4; string = pool_read2(CONNECTION(backend, i), len); if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process query"), - errdetail("error while reading rest of message from backend %d", i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process query"), + errdetail("error while reading rest of message from backend %d", i))); } else { string = pool_read_string(CONNECTION(backend, i), &len, 0); if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process query"), - errdetail("error while reading rest of message from backend %d", i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process query"), + errdetail("error while reading rest of message from backend %d", i))); } } } @@ -410,9 +443,10 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, /* reload config file */ if (got_sighup) { - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); if (pool_config->enable_pool_hba) load_hba(get_hba_file_name()); got_sighup = 0; @@ -423,14 +457,16 @@ POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, /* * send simple query message to a node. */ -void send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, int major) +void +send_simplequery_message(POOL_CONNECTION * backend, int len, char *string, int major) { /* forward the query to the backend */ pool_write(backend, "Q", 1); if (major == PROTO_MAJOR_V3) { - int sendlen = htonl(len + 4); + int sendlen = htonl(len + 4); + pool_write(backend, &sendlen, sizeof(sendlen)); } pool_write_and_flush(backend, string, len); @@ -444,14 +480,15 @@ void send_simplequery_message(POOL_CONNECTION *backend, int len, char *string, i * database consistency. */ -void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion, int pid, int key) +void +wait_for_query_response_with_trans_cleanup(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion, int pid, int key) { - PG_TRY(); - { - wait_for_query_response(frontend, backend, protoVersion); - } - PG_CATCH(); - { + PG_TRY(); + { + wait_for_query_response(frontend, backend, protoVersion); + } + PG_CATCH(); + { if (REPLICATION) { /* Cancel current transaction */ @@ -459,14 +496,15 @@ void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_ cancel_packet.protoVersion = htonl(PROTO_CANCEL); cancel_packet.pid = pid; - cancel_packet.key= key; + cancel_packet.key = key; cancel_request(&cancel_packet); } - PG_RE_THROW(); - } - PG_END_TRY(); + PG_RE_THROW(); + } + PG_END_TRY(); } + /* * Wait for query response from single node. If frontend is not NULL, * also check frontend connection by writing dummy parameter status @@ -474,16 +512,17 @@ void wait_for_query_response_with_trans_cleanup(POOL_CONNECTION *frontend, POOL_ * since there's no point in that waiting until backend returns * response. */ -POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, int protoVersion) +POOL_STATUS +wait_for_query_response(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, int protoVersion) { #define DUMMY_PARAMETER "pgpool_dummy_param" #define DUMMY_VALUE "pgpool_dummy_value" - int status; - int plen; + int status; + int plen; ereport(DEBUG1, - (errmsg("waiting for query response"), + (errmsg("waiting for query response"), errdetail("waiting for backend:%d to complete the query", backend->db_node_id))); for (;;) { @@ -492,34 +531,38 @@ POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION * status = pool_check_fd(backend); pool_set_timeout(-1); - if (status < 0) /* error ? */ + if (status < 0) /* error ? */ { - ereport(ERROR, - (errmsg("backend error occured while waiting for backend response"))); + ereport(ERROR, + (errmsg("backend error occured while waiting for backend response"))); } else if (frontend != NULL && status > 0) { /* - * If data from backend is not ready, check frontend connection by sending dummy - * parameter status packet. + * If data from backend is not ready, check frontend connection by + * sending dummy parameter status packet. */ if (protoVersion == PROTO_MAJOR_V3) { - /* Write dummy parameter staus packet to check if the socket to frontend is ok */ + /* + * Write dummy parameter staus packet to check if the socket + * to frontend is ok + */ pool_write(frontend, "S", 1); - plen = sizeof(DUMMY_PARAMETER)+sizeof(DUMMY_VALUE)+sizeof(plen); + plen = sizeof(DUMMY_PARAMETER) + sizeof(DUMMY_VALUE) + sizeof(plen); plen = htonl(plen); pool_write(frontend, &plen, sizeof(plen)); pool_write(frontend, DUMMY_PARAMETER, sizeof(DUMMY_PARAMETER)); pool_write(frontend, DUMMY_VALUE, sizeof(DUMMY_VALUE)); if (pool_flush_it(frontend) < 0) { - ereport(FRONTEND_ERROR, - (errmsg("unable to to flush data to frontend"), - errdetail("frontend error occured while waiting for backend reply"))); + ereport(FRONTEND_ERROR, + (errmsg("unable to to flush data to frontend"), + errdetail("frontend error occured while waiting for backend reply"))); } - } else /* Protocol version 2 */ + } + else /* Protocol version 2 */ { /* * If you want to monitor client connection even if you are using V2 protocol, @@ -529,14 +572,17 @@ POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION * #ifdef SEND_NOTICE_ON_PROTO2 static char *notice_message = {"keep alive checking from pgpool-II"}; - /* Write notice message packet to check if the socket to frontend is ok */ + /* + * Write notice message packet to check if the socket to + * frontend is ok + */ pool_write(frontend, "N", 1); - pool_write(frontend, notice_message, strlen(notice_message)+1); + pool_write(frontend, notice_message, strlen(notice_message) + 1); if (pool_flush_it(frontend) < 0) { - ereport(FRONTEND_ERROR, - (errmsg("unable to to flush data to frontend"), - errdetail("frontend error occured while waiting for backend reply"))); + ereport(FRONTEND_ERROR, + (errmsg("unable to to flush data to frontend"), + errdetail("frontend error occured while waiting for backend reply"))); } #endif @@ -553,12 +599,13 @@ POOL_STATUS wait_for_query_response(POOL_CONNECTION *frontend, POOL_CONNECTION * /* * Extended query protocol has to send Flush message. */ -POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, - int node_id, char *kind, - int len, char *string) +POOL_STATUS +send_extended_protocol_message(POOL_CONNECTION_POOL * backend, + int node_id, char *kind, + int len, char *string) { POOL_CONNECTION *cp = CONNECTION(backend, node_id); - int sendlen; + int sendlen; /* forward the query to the backend */ pool_write(cp, kind, 1); @@ -569,8 +616,8 @@ POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, if (!SL_MODE) { /* - * send "Flush" message so that backend notices us - * the completion of the command + * send "Flush" message so that backend notices us the completion of + * the command */ pool_write(cp, "H", 1); sendlen = htonl(4); @@ -585,7 +632,8 @@ POOL_STATUS send_extended_protocol_message(POOL_CONNECTION_POOL *backend, /* * wait until read data is ready */ -int synchronize(POOL_CONNECTION *cp) +int +synchronize(POOL_CONNECTION * cp) { return pool_check_fd(cp); } @@ -594,7 +642,8 @@ int synchronize(POOL_CONNECTION *cp) * Set timeout in seconds for pool_check_fd * if timeoutval < 0, we assume no timeout (wait forever). */ -void pool_set_timeout(int timeoutval) +void +pool_set_timeout(int timeoutval) { if (timeoutval >= 0) timeoutsec = timeoutval; @@ -606,19 +655,20 @@ void pool_set_timeout(int timeoutval) * Wait until read data is ready. * return values: 0: normal 1: data is not ready -1: error */ -int pool_check_fd(POOL_CONNECTION *cp) +int +pool_check_fd(POOL_CONNECTION * cp) { - fd_set readmask; - fd_set exceptmask; - int fd; - int fds; + fd_set readmask; + fd_set exceptmask; + int fd; + int fds; struct timeval timeout; struct timeval *timeoutp; - int save_errno; + int save_errno; /* - * If SSL is enabled, we need to check SSL internal buffer - * is empty or not first. Otherwise select(2) will stuck. + * If SSL is enabled, we need to check SSL internal buffer is empty or not + * first. Otherwise select(2) will stuck. */ if (pool_ssl_pending(cp)) { @@ -643,7 +693,7 @@ int pool_check_fd(POOL_CONNECTION *cp) FD_SET(fd, &readmask); FD_SET(fd, &exceptmask); - fds = select(fd+1, &readmask, NULL, &exceptmask, timeoutp); + fds = select(fd + 1, &readmask, NULL, &exceptmask, timeoutp); save_errno = errno; if (fds == -1) { @@ -684,12 +734,13 @@ int pool_check_fd(POOL_CONNECTION *cp) * interruption while calling this function. Otherwise the number of * valid backends might be changed by failover/failback. */ -void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend) +void +pool_send_frontend_exits(POOL_CONNECTION_POOL * backend) { - int len; - int i; + int len; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { /* * send a terminate message to backend if there's an existing @@ -709,8 +760,8 @@ void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend) * XXX we cannot call pool_flush() here since backend may already * close the socket and pool_flush() automatically invokes fail * over handler. This could happen in copy command (remember the - * famous "lost synchronization with server, resetting - * connection" message) + * famous "lost synchronization with server, resetting connection" + * message) */ pool_set_nonblock(CONNECTION(backend, i)->fd); pool_flush_it(CONNECTION(backend, i)); @@ -725,14 +776,16 @@ void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend) * ------------------------------------------------------- */ -POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +SimpleForwardToFrontend(char kind, POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - int len, len1 = 0; - char *p = NULL; - char *p1 = NULL; - int sendlen; - int i; + int len, + len1 = 0; + char *p = NULL; + char *p1 = NULL; + int sendlen; + int i; pool_read(MASTER(backend), &len, sizeof(len)); @@ -742,20 +795,20 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, p = pool_read2(MASTER(backend), len); if (p == NULL) - ereport(ERROR, - (errmsg("unable to forward message to frontend"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("unable to forward message to frontend"), + errdetail("read from backend failed"))); p1 = palloc(len); memcpy(p1, p, len); /* - * If we received a notification message in master/slave mode, - * other backends will not receive the message. - * So we should skip other nodes otherwise we will hang in pool_read. + * If we received a notification message in master/slave mode, other + * backends will not receive the message. So we should skip other nodes + * otherwise we will hang in pool_read. */ if (!MASTER_SLAVE || kind != 'A') { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { #ifdef NOT_USED if (use_sync_map == POOL_SYNC_MAP_EMPTY) @@ -767,7 +820,7 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, #ifdef NOT_USED if (use_sync_map == POOL_SYNC_MAP_IS_VALID && !pool_is_set_sync_map(i)) { - continue; + continue; } #endif @@ -778,22 +831,22 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, p = pool_read2(CONNECTION(backend, i), len); if (p == NULL) - ereport(ERROR, - (errmsg("unable to forward message to frontend"), - errdetail("read on backend node failed"))); + ereport(ERROR, + (errmsg("unable to forward message to frontend"), + errdetail("read on backend node failed"))); if (len != len1) { ereport(DEBUG1, - (errmsg("SimpleForwardToFrontend: length does not match between backends master(%d) %d th backend(%d) kind:(%c)", - len, i, len1, kind))); + (errmsg("SimpleForwardToFrontend: length does not match between backends master(%d) %d th backend(%d) kind:(%c)", + len, i, len1, kind))); } } } } pool_write(frontend, &kind, 1); - sendlen = htonl(len1+4); + sendlen = htonl(len1 + 4); pool_write(frontend, &sendlen, sizeof(sendlen)); /* @@ -832,37 +885,40 @@ POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, if (kind == 'E') { /* - * check if the error was PANIC or FATAL. If so, we just flush - * the message and exit since the backend will close the - * channel immediately. + * check if the error was PANIC or FATAL. If so, we just flush the + * message and exit since the backend will close the channel + * immediately. */ if (is_panic_or_fatal_error(p1, MAJOR(backend))) - ereport(ERROR, - (errmsg("unable to forward message to frontend"), - errdetail("FATAL error occured on backend"))); + ereport(ERROR, + (errmsg("unable to forward message to frontend"), + errdetail("FATAL error occured on backend"))); } pfree(p1); return POOL_CONTINUE; } -POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +SimpleForwardToBackend(char kind, POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + int len, char *contents) { - int sendlen; - int i; + int sendlen; + int i; + sendlen = htonl(len + 4); #ifdef DEBUG - char msgbuf[256]; + char msgbuf[256]; #endif if (len == 0) { - /* We assume that we can always forward to every node - * regardless running mode. Am I correct? + /* + * We assume that we can always forward to every node regardless + * running mode. Am I correct? */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -872,18 +928,18 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, #endif pool_write(CONNECTION(backend, i), &kind, 1); - pool_write_and_flush(CONNECTION(backend,i), &sendlen, sizeof(sendlen)); + pool_write_and_flush(CONNECTION(backend, i), &sendlen, sizeof(sendlen)); } } return POOL_CONTINUE; } else if (len < 0) - ereport(ERROR, - (errmsg("unable to forward message to frontend"), - errdetail("invalid message length:%d for message:%c", len, kind))); + ereport(ERROR, + (errmsg("unable to forward message to frontend"), + errdetail("invalid message length:%d for message:%c", len, kind))); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -893,7 +949,7 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, #endif pool_write(CONNECTION(backend, i), &kind, 1); - pool_write(CONNECTION(backend,i), &sendlen, sizeof(sendlen)); + pool_write(CONNECTION(backend, i), &sendlen, sizeof(sendlen)); pool_write_and_flush(CONNECTION(backend, i), contents, len); } } @@ -901,32 +957,35 @@ POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +POOL_STATUS +ParameterStatus(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - int len, len1 = 0; - int *len_array; - int sendlen; - char *p; - char *name; - char *value; + int len, + len1 = 0; + int *len_array; + int sendlen; + char *p; + char *name; + char *value; POOL_STATUS status; - char parambuf[1024]; /* parameter + value string buffer. XXX is this enough? */ - int i; + char parambuf[1024]; /* parameter + value string buffer. XXX is + * this enough? */ + int i; pool_write(frontend, "S", 1); len_array = pool_read_message_length2(backend); if (len_array == NULL) - ereport(ERROR, - (errmsg("unable to process parameter status"), - errdetail("read on backend failed"))); + ereport(ERROR, + (errmsg("unable to process parameter status"), + errdetail("read on backend failed"))); len = len_array[MASTER_NODE_ID]; sendlen = htonl(len); pool_write(frontend, &sendlen, sizeof(sendlen)); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -935,14 +994,14 @@ POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac p = pool_read2(CONNECTION(backend, i), len); if (p == NULL) - ereport(ERROR, - (errmsg("unable to process parameter status"), - errdetail("could not read from backend"))); + ereport(ERROR, + (errmsg("unable to process parameter status"), + errdetail("could not read from backend"))); name = p; value = p + strlen(name) + 1; ereport(DEBUG1, - (errmsg("process parameter status"), + (errmsg("process parameter status"), errdetail("backend:%d name:\"%s\" value:\"%s\"", i, name, value))); if (IS_MASTER_NODE_ID(i)) @@ -965,9 +1024,10 @@ POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* * Reset all state variables */ -void reset_variables(void) +void +reset_variables(void) { - if(pool_get_session_context(true)) + if (pool_get_session_context(true)) pool_unset_query_in_progress(); } @@ -976,7 +1036,8 @@ void reset_variables(void) * if connection_cache == 0, we don't need reset_query. * but we need reset prepared list. */ -void reset_connection(void) +void +reset_connection(void) { reset_variables(); pool_clear_sent_message_list(); @@ -988,12 +1049,12 @@ void reset_connection(void) * 0: no query was issued 1: a query was issued 2: no more queries remain -1: error */ static int - reset_backend(POOL_CONNECTION_POOL *backend, int qcnt) +reset_backend(POOL_CONNECTION_POOL * backend, int qcnt) { - char *query; - int qn; - int i; - bool need_to_abort; + char *query; + int qn; + int i; + bool need_to_abort; POOL_SESSION_CONTEXT *session_context; POOL_TEMP_QUERY_CACHE *cache; @@ -1029,7 +1090,7 @@ static int /* If transaction state are all idle, we don't need to issue ABORT */ need_to_abort = false; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && TSTATE(backend, i) != 'I') need_to_abort = true; @@ -1046,7 +1107,7 @@ static int pool_unset_query_in_progress(); } - if (SimpleQuery(NULL, backend, strlen(query)+1, query) != POOL_CONTINUE) + if (SimpleQuery(NULL, backend, strlen(query) + 1, query) != POOL_CONTINUE) { pool_set_timeout(-1); return -1; @@ -1058,9 +1119,10 @@ static int if (cache) { pool_discard_temp_query_cache(cache); + /* - * Reset temp_cache pointer in the current query context - * so that we don't double free memory. + * Reset temp_cache pointer in the current query context so that we + * don't double free memory. */ session_context->query_context->temp_cache = NULL; } @@ -1083,20 +1145,20 @@ static int * * Note that for SELECT this function returns false. */ -bool is_select_query(Node *node, char *sql) +bool +is_select_query(Node *node, char *sql) { if (node == NULL) return false; /* - * 2009/5/1 Tatsuo says: This test is not bogus. As of 2.2, pgpool - * sets Portal->sql_string to NULL for SQL command PREPARE. - * Usually this is ok, since in most cases SQL command EXECUTE - * follows anyway. Problem is, some applications mix PREPARE with - * extended protocol command "EXECUTE" and so on. Execute() seems - * to think this never happens but it is not real. Someday we - * should extract actual query string from PrepareStmt->query and - * set it to Portal->sql_string. + * 2009/5/1 Tatsuo says: This test is not bogus. As of 2.2, pgpool sets + * Portal->sql_string to NULL for SQL command PREPARE. Usually this is ok, + * since in most cases SQL command EXECUTE follows anyway. Problem is, + * some applications mix PREPARE with extended protocol command "EXECUTE" + * and so on. Execute() seems to think this never happens but it is not + * real. Someday we should extract actual query string from + * PrepareStmt->query and set it to Portal->sql_string. */ if (sql == NULL) return false; @@ -1112,7 +1174,7 @@ bool is_select_query(Node *node, char *sql) { SelectStmt *select_stmt; - select_stmt = (SelectStmt *)node; + select_stmt = (SelectStmt *) node; if (select_stmt->intoClause || select_stmt->lockingClause) return false; @@ -1120,11 +1182,13 @@ bool is_select_query(Node *node, char *sql) /* non-SELECT query in WITH clause ? */ if (select_stmt->withClause) { - List *ctes = select_stmt->withClause->ctes; + List *ctes = select_stmt->withClause->ctes; ListCell *cte_item; + foreach(cte_item, ctes) { - CommonTableExpr *cte = (CommonTableExpr *)lfirst(cte_item); + CommonTableExpr *cte = (CommonTableExpr *) lfirst(cte_item); + if (!IsA(cte->ctequery, SelectStmt)) return false; } @@ -1140,15 +1204,15 @@ bool is_select_query(Node *node, char *sql) } else if (IsA(node, CopyStmt)) { - CopyStmt *copy_stmt = (CopyStmt *)node; + CopyStmt *copy_stmt = (CopyStmt *) node; if (copy_stmt->is_from) return false; - else if (copy_stmt->filename == NULL ) + else if (copy_stmt->filename == NULL) { if (copy_stmt->query == NULL) return true; - else if (copy_stmt->query && IsA(copy_stmt->query, SelectStmt)) + else if (copy_stmt->query && IsA(copy_stmt->query, SelectStmt)) return true; else return false; @@ -1158,13 +1222,13 @@ bool is_select_query(Node *node, char *sql) } else if (IsA(node, ExplainStmt)) { - ExplainStmt * explain_stmt = (ExplainStmt *)node; - Node *query = explain_stmt->query; - ListCell *lc; - bool analyze = false; + ExplainStmt *explain_stmt = (ExplainStmt *) node; + Node *query = explain_stmt->query; + ListCell *lc; + bool analyze = false; /* Check to see if this is EXPLAIN ANALYZE */ - foreach (lc, explain_stmt->options) + foreach(lc, explain_stmt->options) { DefElem *opt = (DefElem *) lfirst(lc); @@ -1178,11 +1242,12 @@ bool is_select_query(Node *node, char *sql) if (IsA(query, SelectStmt)) { /* - * If query is SELECT and there's no ANALYZE option, we - * can always load balance. + * If query is SELECT and there's no ANALYZE option, we can always + * load balance. */ if (!analyze) return true; + /* * If ANALYZE, we need to check function calls. */ @@ -1193,14 +1258,14 @@ bool is_select_query(Node *node, char *sql) else { /* - * Other than SELECT can be load balance only if ANALYZE - * is not specified. + * Other than SELECT can be load balance only if ANALYZE is not + * specified. */ if (!analyze) return true; } } - else if (IsA(node, VariableShowStmt)) /* SHOW command */ + else if (IsA(node, VariableShowStmt)) /* SHOW command */ return true; return false; @@ -1210,7 +1275,8 @@ bool is_select_query(Node *node, char *sql) * Returns true if SQL is transaction commit or rollback command (COMMIT, * END TRANSACTION, ROLLBACK or ABORT) */ -bool is_commit_or_rollback_query(Node *node) +bool +is_commit_or_rollback_query(Node *node) { return is_commit_query(node) || is_rollback_query(node); } @@ -1219,14 +1285,15 @@ bool is_commit_or_rollback_query(Node *node) * Returns true if SQL is transaction commit command (COMMIT or END * TRANSACTION) */ -bool is_commit_query(Node *node) +bool +is_commit_query(Node *node) { TransactionStmt *stmt; if (node == NULL || !IsA(node, TransactionStmt)) return false; - stmt = (TransactionStmt *)node; + stmt = (TransactionStmt *) node; return stmt->kind == TRANS_STMT_COMMIT; } @@ -1234,27 +1301,29 @@ bool is_commit_query(Node *node) * Returns true if SQL is transaction rollback command (ROLLBACK or * ABORT) */ -bool is_rollback_query(Node *node) +bool +is_rollback_query(Node *node) { TransactionStmt *stmt; if (node == NULL || !IsA(node, TransactionStmt)) return false; - stmt = (TransactionStmt *)node; + stmt = (TransactionStmt *) node; return stmt->kind == TRANS_STMT_ROLLBACK; } /* * send error message to frontend */ -void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - int line) +void +pool_send_error_message(POOL_CONNECTION * frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line) { pool_send_severity_message(frontend, protoMajor, code, message, detail, hint, file, "ERROR", line); } @@ -1262,13 +1331,14 @@ void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, /* * send fatal message to frontend */ -void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - int line) +void +pool_send_fatal_message(POOL_CONNECTION * frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line) { pool_send_severity_message(frontend, protoMajor, code, message, detail, hint, file, "FATAL", line); } @@ -1276,14 +1346,15 @@ void pool_send_fatal_message(POOL_CONNECTION *frontend, int protoMajor, /* * send severity message to frontend */ -void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, - char *code, - char *message, - char *detail, - char *hint, - char *file, - char *severity, - int line) +void +pool_send_severity_message(POOL_CONNECTION * frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + char *severity, + int line) { /* * Buffer length for each message part @@ -1301,15 +1372,15 @@ void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, if (protoMajor == PROTO_MAJOR_V2) { pool_write(frontend, "E", 1); - pool_write_and_flush(frontend, message, strlen(message)+1); + pool_write_and_flush(frontend, message, strlen(message) + 1); } else if (protoMajor == PROTO_MAJOR_V3) { - char data[MAXDATA]; - char msgbuf[MAXMSGBUF+1]; - int len; - int thislen; - int sendlen; + char data[MAXDATA]; + char msgbuf[MAXMSGBUF + 1]; + int len; + int thislen; + int sendlen; len = 0; memset(data, 0, MAXDATA); @@ -1319,19 +1390,19 @@ void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, /* error level */ thislen = snprintf(msgbuf, MAXMSGBUF, "S%s", severity); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; /* code */ thislen = snprintf(msgbuf, MAXMSGBUF, "C%s", code); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; /* message */ thislen = snprintf(msgbuf, MAXMSGBUF, "M%s", message); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; /* detail */ @@ -1339,7 +1410,7 @@ void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, { thislen = snprintf(msgbuf, MAXMSGBUF, "D%s", detail); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; } @@ -1348,20 +1419,20 @@ void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, { thislen = snprintf(msgbuf, MAXMSGBUF, "H%s", hint); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; } /* file */ thislen = snprintf(msgbuf, MAXMSGBUF, "F%s", file); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; /* line */ thislen = snprintf(msgbuf, MAXMSGBUF, "L%d", line); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; /* stop null */ @@ -1380,9 +1451,11 @@ void pool_send_severity_message(POOL_CONNECTION *frontend, int protoMajor, pool_unset_nonblock(frontend->fd); } -void pool_send_readyforquery(POOL_CONNECTION *frontend) +void +pool_send_readyforquery(POOL_CONNECTION * frontend) { - int len; + int len; + pool_write(frontend, "Z", 1); len = 5; len = htonl(len); @@ -1399,59 +1472,59 @@ void pool_send_readyforquery(POOL_CONNECTION *frontend) * If no_ready_for_query is non 0, returns without reading the packet * length for ReadyForQuery. This mode is necessary when called from ReadyForQuery(). */ -POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, - char *query, int protoMajor, int pid, int key, int no_ready_for_query) +POOL_STATUS +do_command(POOL_CONNECTION * frontend, POOL_CONNECTION * backend, + char *query, int protoMajor, int pid, int key, int no_ready_for_query) { - int len; - char kind; - char *string; - int deadlock_detected = 0; + int len; + char kind; + char *string; + int deadlock_detected = 0; + ereport(DEBUG1, - (errmsg("do_command: Query:\"%s\"", query))); + (errmsg("do_command: Query:\"%s\"", query))); /* send the query to the backend */ - send_simplequery_message(backend, strlen(query)+1, query, protoMajor); + send_simplequery_message(backend, strlen(query) + 1, query, protoMajor); /* - * Wait for response from badckend while polling frontend connection is ok. - * If not, cancel the transaction. + * Wait for response from badckend while polling frontend connection is + * ok. If not, cancel the transaction. */ - wait_for_query_response_with_trans_cleanup(frontend, - backend, - protoMajor, - pid, - key); - - /* - * We must check deadlock error here. If a deadlock error is - * detected by a backend, other backend might not be noticed the - * error. In this case caller should send an error query to the - * backend to abort the transaction. Otherwise the transaction - * state might vary among backends (idle in transaction vs. abort). + wait_for_query_response_with_trans_cleanup(frontend, + backend, + protoMajor, + pid, + key); + + /* + * We must check deadlock error here. If a deadlock error is detected by a + * backend, other backend might not be noticed the error. In this case + * caller should send an error query to the backend to abort the + * transaction. Otherwise the transaction state might vary among backends + * (idle in transaction vs. abort). */ deadlock_detected = detect_deadlock_error(backend, protoMajor); /* - * Continue to read packets until we get ReadForQuery (Z). - * Until that we may recieve one of: + * Continue to read packets until we get ReadForQuery (Z). Until that we + * may recieve one of: * - * N: Notice response - * E: Error response - * C: Comand complete + * N: Notice response E: Error response C: Comand complete * - * XXX: we ignore Notice and Error here. Even notice/error - * messages are not sent to the frontend. May be it's ok since the - * error was caused by our internal use of SQL command (otherwise users - * will be confused). + * XXX: we ignore Notice and Error here. Even notice/error messages are + * not sent to the frontend. May be it's ok since the error was caused by + * our internal use of SQL command (otherwise users will be confused). */ - for(;;) + for (;;) { pool_read(backend, &kind, sizeof(kind)); ereport(DEBUG1, - (errmsg("do_command: kind: '%c'", kind))); + (errmsg("do_command: kind: '%c'", kind))); if (kind == 'Z') /* Ready for Query? */ - break; /* get out the loop without reading message lenghth */ + break; /* get out the loop without reading message + * lenghth */ if (protoMajor == PROTO_MAJOR_V3) { @@ -1461,29 +1534,30 @@ POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, if (kind != 'N' && kind != 'E' && kind != 'S' && kind != 'C' && kind != 'A') { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("kind is not N, E, S, C or A(%02x)", kind))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("kind is not N, E, S, C or A(%02x)", kind))); } string = pool_read2(backend, len); if (string == NULL) { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("unable to read message from backend"))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("unable to read message from backend"))); } /* - * It is possible that we receive a notification response - * ('A') from one of backends prior to "ready for query" - * response if LISTEN and NOTIFY are issued in a same - * connection. So we need to save notification response to - * stack buffer so that we could retrieve it later on. + * It is possible that we receive a notification response ('A') + * from one of backends prior to "ready for query" response if + * LISTEN and NOTIFY are issued in a same connection. So we need + * to save notification response to stack buffer so that we could + * retrieve it later on. */ if (kind == 'A') { - int nlen = htonl(len+4); + int nlen = htonl(len + 4); + pool_push(backend, &kind, sizeof(kind)); pool_push(backend, &nlen, sizeof(nlen)); pool_push(backend, string, len); @@ -1494,9 +1568,9 @@ POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, string = pool_read_string(backend, &len, 0); if (string == NULL) { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("unable to read reset message from backend"))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("unable to read reset message from backend"))); } if (kind == 'C') { @@ -1508,13 +1582,13 @@ POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, } } - if(kind == 'E') + if (kind == 'E') { if (is_panic_or_fatal_error(string, protoMajor)) { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("backend error: \"%s\"",string))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("backend error: \"%s\"", string))); } } } @@ -1527,6 +1601,7 @@ POOL_STATUS do_command(POOL_CONNECTION *frontend, POOL_CONNECTION *backend, * "goto". Congratulations. */ #ifdef NOT_USED + /* * Expecting CompleteCommand */ @@ -1535,9 +1610,9 @@ retry_read_packet: if (kind == 'E') { - ereport(LOG, - (errmsg("do command failed"), - errdetail("backend does not successfully complete command %s status %c", query, kind))); + ereport(LOG, + (errmsg("do command failed"), + errdetail("backend does not successfully complete command %s status %c", query, kind))); } /* @@ -1549,23 +1624,23 @@ retry_read_packet: len = ntohl(len) - 4; string = pool_read2(backend, len); if (string == NULL) - ereport(ERROR, - (errmsg("do command failed"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("read from backend failed"))); - ereport(DEBUG2, - (errmsg("do command: command tag: %s", string))); + ereport(DEBUG2, + (errmsg("do command: command tag: %s", string))); } else { string = pool_read_string(backend, &len, 0); if (string == NULL) - ereport(ERROR, - (errmsg("do command failed"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("read from backend failed"))); } - if (kind == 'N') /* warning? */ + if (kind == 'N') /* warning? */ goto retry_read_packet; /* @@ -1575,9 +1650,9 @@ retry_read_packet: if (kind != 'Z') { - ereport(ERROR, - (errmsg("do command failed"), - errdetail("backend returns %c while expecting ReadyForQuery", kind))); + ereport(ERROR, + (errmsg("do command failed"), + errdetail("backend returns %c while expecting ReadyForQuery", kind))); } #endif @@ -1596,8 +1671,8 @@ retry_read_packet: backend->tstate = kind; - ereport(DEBUG2, - (errmsg("do_command: transaction state: %c", kind))); + ereport(DEBUG2, + (errmsg("do_command: transaction state: %c", kind))); } return deadlock_detected ? POOL_DEADLOCK : POOL_CONTINUE; @@ -1611,32 +1686,32 @@ retry_read_packet: * SELECT query is sent to master only. * If SELECT is error, we must abort transaction on other nodes. */ -void do_error_command(POOL_CONNECTION *backend, int major) +void +do_error_command(POOL_CONNECTION * backend, int major) { - char *error_query = POOL_ERROR_QUERY; - int len; - char kind; - char *string; + char *error_query = POOL_ERROR_QUERY; + int len; + char kind; + char *string; send_simplequery_message(backend, strlen(error_query) + 1, error_query, major); + /* - * Continue to read packets until we get Error response (E). - * Until that we may recieve one of: + * Continue to read packets until we get Error response (E). Until that we + * may recieve one of: * - * N: Notice response - * C: Comand complete + * N: Notice response C: Comand complete * - * XXX: we ignore Notice here. Even notice messages are not sent - * to the frontend. May be it's ok since the error was caused by - * our internal use of SQL command (otherwise users will be - * confused). + * XXX: we ignore Notice here. Even notice messages are not sent to the + * frontend. May be it's ok since the error was caused by our internal use + * of SQL command (otherwise users will be confused). */ do { pool_read(backend, &kind, sizeof(kind)); - ereport(DEBUG2, - (errmsg("do_error_command: kind: %c", kind))); + ereport(DEBUG2, + (errmsg("do_error_command: kind: %c", kind))); if (major == PROTO_MAJOR_V3) { @@ -1644,17 +1719,17 @@ void do_error_command(POOL_CONNECTION *backend, int major) len = ntohl(len) - 4; string = pool_read2(backend, len); if (string == NULL) - ereport(ERROR, - (errmsg("do error command failed"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("do error command failed"), + errdetail("read from backend failed"))); } else { string = pool_read_string(backend, &len, 0); if (string == NULL) - ereport(ERROR, - (errmsg("do error command failed"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("do error command failed"), + errdetail("read from backend failed"))); } } while (kind != 'E'); @@ -1668,28 +1743,29 @@ void do_error_command(POOL_CONNECTION *backend, int major) * sync transaction status in each node, we send error query to other * than master node to ket them go into abort status. */ -void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int major) +void +do_error_execute_command(POOL_CONNECTION_POOL * backend, int node_id, int major) { - char kind; - char *string; - char msg[1024] = "pgpool_error_portal"; /* large enough */ - int len = strlen(msg); - char buf[8192]; /* memory space is large enough */ - char *p; - int readlen = 0; + char kind; + char *string; + char msg[1024] = "pgpool_error_portal"; /* large enough */ + int len = strlen(msg); + char buf[8192]; /* memory space is large enough */ + char *p; + int readlen = 0; p = buf; memset(msg + len, 0, sizeof(int)); send_extended_protocol_message(backend, node_id, "E", len + 5, msg); /* - * Discard responses from backend until ErrorResponse received. - * Note that we need to preserve non-error responses - * (i.e. ReadyForQuery) and put back them using pool_unread(). - * Otherwise, ReadyForQuery response of DEALLOCATE. This could - * happen if PHP PDO used. (2010/04/21) + * Discard responses from backend until ErrorResponse received. Note that + * we need to preserve non-error responses (i.e. ReadyForQuery) and put + * back them using pool_unread(). Otherwise, ReadyForQuery response of + * DEALLOCATE. This could happen if PHP PDO used. (2010/04/21) */ - do { + do + { pool_read(CONNECTION(backend, node_id), &kind, sizeof(kind)); /* @@ -1716,17 +1792,17 @@ void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int ma len = ntohl(len) - 4; string = pool_read2(CONNECTION(backend, node_id), len); if (string == NULL) - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("do error execute command failed"), + errdetail("read from backend failed"))); if (kind != 'E') { readlen += len; if (readlen >= sizeof(buf)) { - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("not enough space in buffer"))); + ereport(ERROR, + (errmsg("do error execute command failed"), + errdetail("not enough space in buffer"))); } memcpy(p, string, len); @@ -1737,18 +1813,18 @@ void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int ma { string = pool_read_string(CONNECTION(backend, node_id), &len, 0); if (string == NULL) - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("read from backend failed"))); + ereport(ERROR, + (errmsg("do error execute command failed"), + errdetail("read from backend failed"))); if (kind != 'E') { readlen += len; if (readlen >= sizeof(buf)) { - ereport(ERROR, - (errmsg("do error execute command failed"), - errdetail("not enough space in buffer"))); + ereport(ERROR, + (errmsg("do error execute command failed"), + errdetail("not enough space in buffer"))); } memcpy(p, string, len); p += sizeof(len); @@ -1756,20 +1832,22 @@ void do_error_execute_command(POOL_CONNECTION_POOL *backend, int node_id, int ma } } while (kind != 'E'); - if (readlen > 0) - { - /* put messages back to read buffer */ - pool_unread(CONNECTION(backend, node_id), buf, readlen); - } + if (readlen > 0) + { + /* put messages back to read buffer */ + pool_unread(CONNECTION(backend, node_id), buf, readlen); + } } /* * Free POOL_SELECT_RESULT object */ -void free_select_result(POOL_SELECT_RESULT *result) +void +free_select_result(POOL_SELECT_RESULT * result) { - int i, j; - int index; + int i, + j; + int index; if (result == NULL) return; @@ -1780,9 +1858,9 @@ void free_select_result(POOL_SELECT_RESULT *result) if (result->data) { index = 0; - for(i=0;i<result->numrows;i++) + for (i = 0; i < result->numrows; i++) { - for (j=0;j<result->rowdesc->num_attrs;j++) + for (j = 0; j < result->rowdesc->num_attrs; j++) { if (result->data[index]) pfree(result->data[index]); @@ -1796,7 +1874,7 @@ void free_select_result(POOL_SELECT_RESULT *result) { if (result->rowdesc->attrinfo) { - for(i=0;i<result->rowdesc->num_attrs;i++) + for (i = 0; i < result->rowdesc->num_attrs; i++) { if (result->rowdesc->attrinfo[i].attrname) pfree(result->rowdesc->attrinfo[i].attrname); @@ -1817,9 +1895,11 @@ void free_select_result(POOL_SELECT_RESULT *result) * Note: After the introduction of elog API the return type of do_query is changed * to void. and now ereport is thrown in case of error occured within the function */ -void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int major) +void +do_query(POOL_CONNECTION * backend, char *query, POOL_SELECT_RESULT * *result, int major) { -#define DO_QUERY_ALLOC_NUM 1024 /* memory allocation unit for POOL_SELECT_RESULT */ +#define DO_QUERY_ALLOC_NUM 1024 /* memory allocation unit for + * POOL_SELECT_RESULT */ /* * State transition control bits. We expect all following events have @@ -1838,27 +1918,27 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result CLOSE_COMPLETE_RECEIVED | COMMAND_COMPLETE_RECEIVED | \ ROW_DESCRIPTION_RECEIVED | DATA_ROW_RECEIVED) - int i; - int len; - char kind; - char *packet = NULL; - char *p = NULL; - short num_fields = 0; - int num_data; - int intval; - short shortval; + int i; + int len; + char kind; + char *packet = NULL; + char *p = NULL; + short num_fields = 0; + int num_data; + int intval; + short shortval; POOL_SELECT_RESULT *res; - RowDesc *rowdesc; - AttrInfo *attrinfo; + RowDesc *rowdesc; + AttrInfo *attrinfo; - int nbytes; + int nbytes; static char nullmap[8192]; unsigned char mask = 0; - bool doing_extended; - int num_close_complete; - int state; - bool data_pushed; + bool doing_extended; + int num_close_complete; + int state; + bool data_pushed; data_pushed = false; @@ -1876,21 +1956,21 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result num_data = 0; - res->nullflags = palloc(DO_QUERY_ALLOC_NUM*sizeof(int)); - res->data = palloc0(DO_QUERY_ALLOC_NUM*sizeof(char *)); + res->nullflags = palloc(DO_QUERY_ALLOC_NUM * sizeof(int)); + res->data = palloc0(DO_QUERY_ALLOC_NUM * sizeof(char *)); /* - * Send a query to the backend. We use extended query proctocol - * with named statement/portal if we are processing exetended - * query since simple query breaks unnamed statements/portals. - * The name of named statment/unamed statement are "pgpool_PID" - * where PID is the process id of itself. + * Send a query to the backend. We use extended query proctocol with named + * statement/portal if we are processing exetended query since simple + * query breaks unnamed statements/portals. The name of named + * statment/unamed statement are "pgpool_PID" where PID is the process id + * of itself. */ if (pool_get_session_context(true) && pool_is_doing_extended_query_message()) { static char prepared_name[256]; - static int pname_len; - int qlen; + static int pname_len; + int qlen; /* * In streaming replication mode, send flush message before going any @@ -1901,15 +1981,16 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result if (SL_MODE && pool_pending_message_exists()) { data_pushed = pool_push_pending_data(backend); + /* - * ignore_till_sync flag may have been set in pool_push_pending_data(). - * So check it. + * ignore_till_sync flag may have been set in + * pool_push_pending_data(). So check it. */ if (pool_is_ignore_till_sync()) { if (data_pushed) { - int poplen; + int poplen; pool_pop(backend, &poplen); ereport(DEBUG5, @@ -1924,10 +2005,10 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result if (pname_len == 0) { snprintf(prepared_name, sizeof(prepared_name), "pgpool%d", getpid()); - pname_len = strlen(prepared_name)+1; + pname_len = strlen(prepared_name) + 1; } - qlen = strlen(query)+1; + qlen = strlen(query) + 1; /* * Send parse message @@ -1937,9 +2018,9 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result len = htonl(len); pool_write(backend, &len, sizeof(len)); pool_write(backend, prepared_name, pname_len); /* statement */ - pool_write(backend, query, qlen); /* query */ + pool_write(backend, query, qlen); /* query */ shortval = 0; - pool_write(backend, &shortval, sizeof(shortval)); /* num parameters */ + pool_write(backend, &shortval, sizeof(shortval)); /* num parameters */ /* * Send bind message @@ -1951,12 +2032,13 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result pool_write(backend, prepared_name, pname_len); /* portal */ pool_write(backend, prepared_name, pname_len); /* statement */ shortval = 0; - pool_write(backend, &shortval, sizeof(shortval)); /* num parameter format code */ - pool_write(backend, &shortval, sizeof(shortval)); /* num parameter values */ + pool_write(backend, &shortval, sizeof(shortval)); /* num parameter format + * code */ + pool_write(backend, &shortval, sizeof(shortval)); /* num parameter values */ shortval = htons(1); - pool_write(backend, &shortval, sizeof(shortval)); /* num result format */ + pool_write(backend, &shortval, sizeof(shortval)); /* num result format */ shortval = 0; - pool_write(backend, &shortval, sizeof(shortval)); /* result format (text) */ + pool_write(backend, &shortval, sizeof(shortval)); /* result format (text) */ /* * Send close statement message @@ -2007,16 +2089,16 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result /* * Send sync or flush message. If we are in an explicit transaction, - * sending "sync" is safe because it will not break unnamed - * portal. Also this is desirable because if no user queries are sent - * after do_query(), COMMIT command could cause statement time out, - * because flush message does not clear the alarm for statement time - * out which has been set when do_query() issues query. + * sending "sync" is safe because it will not break unnamed portal. + * Also this is desirable because if no user queries are sent after + * do_query(), COMMIT command could cause statement time out, because + * flush message does not clear the alarm for statement time out which + * has been set when do_query() issues query. */ if (backend->tstate == 'T') - pool_write(backend, "S", 1); /* send "sync" message */ + pool_write(backend, "S", 1); /* send "sync" message */ else - pool_write(backend, "H", 1); /* send "flush" message */ + pool_write(backend, "H", 1); /* send "flush" message */ len = htonl(sizeof(len)); pool_write_and_flush(backend, &len, sizeof(len)); } @@ -2028,45 +2110,43 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result /* * Continue to read packets until we get Ready for command('Z') * - * XXX: we ignore other than Z here. Even notice messages are not sent - * to the frontend. May be it's ok since the error was caused by - * our internal use of SQL command (otherwise users will be - * confused). + * XXX: we ignore other than Z here. Even notice messages are not sent to + * the frontend. May be it's ok since the error was caused by our internal + * use of SQL command (otherwise users will be confused). */ num_close_complete = 0; state = 0; - for(;;) + for (;;) { pool_read(backend, &kind, sizeof(kind)); ereport(DEBUG5, (errmsg("do_query: kind: '%c'", kind))); - if (kind == 'E') + if (kind == 'E') { - char *message = NULL; + char *message = NULL; if (pool_extract_error_message(false, backend, major, true, &message) == 1) { /* - * This is fatal. Because: If we operate extended - * query, backend would not accept subsequent commands - * until "sync" message issued. However, if sync - * message is issued, unnamed statement/unnamed portal - * will disappear and will cause lots of problems. If - * we do not operate extended query, ongoing - * transaction is aborted, and subsequent query would - * not accepted. In summary there's no transparent - * way for frontend to handle error case. The only way - * is closing this session. + * This is fatal. Because: If we operate extended query, + * backend would not accept subsequent commands until "sync" + * message issued. However, if sync message is issued, unnamed + * statement/unnamed portal will disappear and will cause lots + * of problems. If we do not operate extended query, ongoing + * transaction is aborted, and subsequent query would not + * accepted. In summary there's no transparent way for + * frontend to handle error case. The only way is closing this + * session. */ - ereport(FATAL, - (return_code(1), - errmsg("Backend throw an error message"), - errdetail("Exiting current session because of an error from backend"), - errhint("BACKEND Error: \"%s\"",message?message:""))); + ereport(FATAL, + (return_code(1), + errmsg("Backend throw an error message"), + errdetail("Exiting current session because of an error from backend"), + errhint("BACKEND Error: \"%s\"", message ? message : ""))); if (message) pfree(message); } @@ -2082,9 +2162,9 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result { packet = pool_read2(backend, len); if (packet == NULL) - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading rest of message"))); + ereport(ERROR, + (errmsg("do query failed"), + errdetail("error while reading rest of message"))); } } @@ -2094,20 +2174,20 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result if (kind == 'C' || kind == 'E' || kind == 'N' || kind == 'P') { - if (pool_read_string(backend, &len, 0) == NULL) + if (pool_read_string(backend, &len, 0) == NULL) { - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading string of message type %c", kind))); + ereport(ERROR, + (errmsg("do query failed"), + errdetail("error while reading string of message type %c", kind))); } } } switch (kind) { - case 'Z': /* Ready for query */ + case 'Z': /* Ready for query */ ereport(DEBUG5, - (errmsg("do_query: received READY FOR QUERY ('%c')",kind))); + (errmsg("do_query: received READY FOR QUERY ('%c')", kind))); if (!doing_extended) return; @@ -2116,52 +2196,56 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result state |= COMMAND_COMPLETE_RECEIVED; break; - case 'C': /* Command Complete */ + case 'C': /* Command Complete */ ereport(DEBUG5, - (errmsg("do_query: received COMMAND COMPLETE ('%c')",kind))); + (errmsg("do_query: received COMMAND COMPLETE ('%c')", kind))); - /* If "sync" message was issued, 'Z' is expected, else we are done with 'C'. */ + /* + * If "sync" message was issued, 'Z' is expected, else we are + * done with 'C'. + */ if (!doing_extended || backend->tstate != 'T') state |= COMMAND_COMPLETE_RECEIVED; + /* - * "Comand Complete" implies data row received status - * if the query was SELECT. If there's no row - * returned, "command complete" comes without row - * data. + * "Comand Complete" implies data row received status if the + * query was SELECT. If there's no row returned, "command + * complete" comes without row data. */ state |= DATA_ROW_RECEIVED; + /* - * For other than SELECT, ROW_DESCRIPTION_RECEIVED - * should be set because we didn't issue DESCRIBE - * message. + * For other than SELECT, ROW_DESCRIPTION_RECEIVED should be + * set because we didn't issue DESCRIBE message. */ state |= ROW_DESCRIPTION_RECEIVED; break; - case '1': /* Parse complete */ + case '1': /* Parse complete */ ereport(DEBUG5, - (errmsg("do_query: received PARSE COMPLETE ('%c')",kind))); + (errmsg("do_query: received PARSE COMPLETE ('%c')", kind))); state |= PARSE_COMPLETE_RECEIVED; break; - case '2': /* Bind complete */ + case '2': /* Bind complete */ ereport(DEBUG5, - (errmsg("do_query: received BIND COMPLETE ('%c')",kind))); + (errmsg("do_query: received BIND COMPLETE ('%c')", kind))); state |= BIND_COMPLETE_RECEIVED; break; - case '3': /* Close complete */ + case '3': /* Close complete */ ereport(DEBUG5, - (errmsg("do_query: received CLOSE COMPLETE ('%c')",kind))); + (errmsg("do_query: received CLOSE COMPLETE ('%c')", kind))); if (state == 0) { - /* Close complete message received prior to parse complete + /* + * Close complete message received prior to parse complete * message. It is likely that a close message was not * pushed in pool_push_pending_data(). Push the message * now. - */ + */ pool_push(backend, "3", 1); len = htonl(4); pool_push(backend, &len, sizeof(len)); @@ -2175,14 +2259,14 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result } break; - case 'T': /* Row Description */ + case 'T': /* Row Description */ state |= ROW_DESCRIPTION_RECEIVED; ereport(DEBUG5, - (errmsg("do_query: received ROW DESCRIPTION ('%c')",kind))); + (errmsg("do_query: received ROW DESCRIPTION ('%c')", kind))); if (major == PROTO_MAJOR_V3) { - if(packet) + if (packet) { p = packet; memcpy(&shortval, p, sizeof(short)); @@ -2191,25 +2275,25 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result else { ereport(ERROR, - (errmsg("do query failed, no data received for ROW DESCRIPTION ('%c') packet",kind))); + (errmsg("do query failed, no data received for ROW DESCRIPTION ('%c') packet", kind))); } } else { pool_read(backend, &shortval, sizeof(short)); } - num_fields = ntohs(shortval); /* number of fields */ + num_fields = ntohs(shortval); /* number of fields */ ereport(DEBUG5, (errmsg("do_query: row description: num_fileds: %d", num_fields))); if (num_fields > 0) { rowdesc->num_attrs = num_fields; - attrinfo = palloc(sizeof(*attrinfo)*num_fields); + attrinfo = palloc(sizeof(*attrinfo) * num_fields); rowdesc->attrinfo = attrinfo; /* extract attribute info */ - for (i = 0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { if (major == PROTO_MAJOR_V3) { @@ -2232,7 +2316,8 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result memcpy(&intval, p, sizeof(int)); attrinfo->mod = htonl(intval); p += sizeof(int); - p += sizeof(short); /* skip format code since we use "text" anyway */ + p += sizeof(short); /* skip format code since we + * use "text" anyway */ } else { @@ -2252,15 +2337,15 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result } break; - case 'D': /* data row */ + case 'D': /* data row */ state |= DATA_ROW_RECEIVED; ereport(DEBUG5, - (errmsg("do_query: received DATA ROW ('%c')",kind))); + (errmsg("do_query: received DATA ROW ('%c')", kind))); if (major == PROTO_MAJOR_V3) { p = packet; - if(p) + if (p) { memcpy(&shortval, p, sizeof(short)); num_fields = htons(shortval); @@ -2268,29 +2353,29 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result } else ereport(ERROR, - (errmsg("do query failed"), + (errmsg("do query failed"), errdetail("error while reading data"))); } if (num_fields > 0) { - if (major == PROTO_MAJOR_V2) - { - nbytes = (num_fields + 7)/8; + if (major == PROTO_MAJOR_V2) + { + nbytes = (num_fields + 7) / 8; - if (nbytes <= 0) - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading null bitmap"))); + if (nbytes <= 0) + ereport(ERROR, + (errmsg("do query failed"), + errdetail("error while reading null bitmap"))); - pool_read(backend, nullmap, nbytes); - } + pool_read(backend, nullmap, nbytes); + } res->numrows++; - for (i=0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { if (major == PROTO_MAJOR_V3) { @@ -2315,7 +2400,7 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result mask = 0x80; /* NOT NULL? */ - if (mask & nullmap[i/8]) + if (mask & nullmap[i / 8]) { /* field size */ pool_read(backend, &len, sizeof(int)); @@ -2330,9 +2415,9 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result memcpy(res->data[num_data], p, len); *(res->data[num_data] + len) = '\0'; if (res->data[num_data] == NULL) - ereport(ERROR, - (errmsg("do query failed"), - errdetail("error while reading field data"))); + ereport(ERROR, + (errmsg("do query failed"), + errdetail("error while reading field data"))); } } else @@ -2348,9 +2433,9 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result if (num_data % DO_QUERY_ALLOC_NUM == 0) { res->nullflags = repalloc(res->nullflags, - (num_data/DO_QUERY_ALLOC_NUM +1)*DO_QUERY_ALLOC_NUM*sizeof(int)); + (num_data / DO_QUERY_ALLOC_NUM + 1) * DO_QUERY_ALLOC_NUM * sizeof(int)); res->data = repalloc(res->data, - (num_data/DO_QUERY_ALLOC_NUM +1)*DO_QUERY_ALLOC_NUM*sizeof(char *)); + (num_data / DO_QUERY_ALLOC_NUM + 1) * DO_QUERY_ALLOC_NUM * sizeof(char *)); } } } @@ -2370,7 +2455,7 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result if (data_pushed) { - int poplen; + int poplen; pool_pop(backend, &poplen); ereport(DEBUG5, @@ -2387,7 +2472,8 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result * 2: row lock against sequence table is required * 3: row lock against insert_lock table is required */ -int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) +int +need_insert_lock(POOL_CONNECTION_POOL * backend, char *query, Node *node) { /* * Query to know if the target table has SERIAL column or not. @@ -2399,9 +2485,9 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) #define NEXTVALQUERY3 "SELECT count(*) FROM pg_catalog.pg_attrdef AS d, pg_catalog.pg_class AS c WHERE d.adrelid = c.oid AND d.adsrc ~ 'nextval' AND c.oid = pg_catalog.to_regclass('%s')" - char *table; - int result; - static POOL_RELCACHE *relcache; + char *table; + int result; + static POOL_RELCACHE * relcache; /* INSERT statement? */ if (!IsA(node, InsertStmt)) @@ -2427,12 +2513,12 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) return 0; /* - * if insert_lock is true, then check if the table actually uses - * SERIAL data type + * if insert_lock is true, then check if the table actually uses SERIAL + * data type */ /* obtain table name */ - table = get_insert_command_table_name((InsertStmt *)node); + table = get_insert_command_table_name((InsertStmt *) node); if (table == NULL) { ereport(LOG, @@ -2448,7 +2534,7 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) */ if (!relcache) { - char *query; + char *query; /* PostgreSQL 9.4 or later has to_regclass() */ if (pool_has_to_regclass()) @@ -2479,11 +2565,11 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) * Search relcache. */ #ifdef USE_TABLE_LOCK - result = pool_search_relcache(relcache, backend, table)==0?0:1; + result = pool_search_relcache(relcache, backend, table) == 0 ? 0 : 1; #elif USE_SEQUENCE_LOCK - result = pool_search_relcache(relcache, backend, table)==0?0:2; + result = pool_search_relcache(relcache, backend, table) == 0 ? 0 : 2; #else - result = pool_search_relcache(relcache, backend, table)==0?0:3; + result = pool_search_relcache(relcache, backend, table) == 0 ? 0 : 3; #endif return result; } @@ -2500,18 +2586,20 @@ int need_insert_lock(POOL_CONNECTION_POOL *backend, char *query, Node *node) * [HACKERS] pgpool versus sequences * [ADMIN] 'SGT DETAIL: Could not open file "pg_clog/05DC": ... */ -POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *query, InsertStmt *node, int lock_kind) +POOL_STATUS +insert_lock(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *query, InsertStmt *node, int lock_kind) { - char *table; - int len = 0; - char qbuf[1024]; - int i, deadlock_detected = 0; - char *adsrc; - char seq_rel_name[MAX_NAME_LEN+1]; - regex_t preg; - size_t nmatch = 2; - regmatch_t pmatch[nmatch]; - static POOL_RELCACHE *relcache; + char *table; + int len = 0; + char qbuf[1024]; + int i, + deadlock_detected = 0; + char *adsrc; + char seq_rel_name[MAX_NAME_LEN + 1]; + regex_t preg; + size_t nmatch = 2; + regmatch_t pmatch[nmatch]; + static POOL_RELCACHE * relcache; POOL_SELECT_RESULT *result; POOL_STATUS status = POOL_CONTINUE; @@ -2542,7 +2630,7 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend */ if (!relcache) { - char *query; + char *query; /* PostgreSQL 9.4 or later has to_regclass() */ if (pool_has_to_regclass()) @@ -2563,10 +2651,10 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend false); if (relcache == NULL) { - ereport(FATAL, - (return_code(2), - errmsg("unable to get insert lock on table"), - errdetail("error while creating relcache"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to get insert lock on table"), + errdetail("error while creating relcache"))); } } @@ -2583,14 +2671,14 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend return POOL_CONTINUE; } ereport(DEBUG1, - (errmsg("getting insert lock on table"), + (errmsg("getting insert lock on table"), errdetail("adsrc: \"%s\"", adsrc))); - if (regcomp(&preg, "nextval\\(+'(.+)'", REG_EXTENDED|REG_NEWLINE) != 0) - ereport(FATAL, - (return_code(2), - errmsg("unable to get insert lock on table"), - errdetail("regex compile failed"))); + if (regcomp(&preg, "nextval\\(+'(.+)'", REG_EXTENDED | REG_NEWLINE) != 0) + ereport(FATAL, + (return_code(2), + errmsg("unable to get insert lock on table"), + errdetail("regex compile failed"))); if (regexec(&preg, adsrc, nmatch, pmatch, 0) == 0) { @@ -2605,13 +2693,13 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend regfree(&preg); if (len == 0) - ereport(FATAL, - (return_code(2), - errmsg("unable to get insert lock on table"), - errdetail("regex no match: pg_attrdef is %s", adsrc))); + ereport(FATAL, + (return_code(2), + errmsg("unable to get insert lock on table"), + errdetail("regex no match: pg_attrdef is %s", adsrc))); ereport(DEBUG1, - (errmsg("getting insert lock on table"), + (errmsg("getting insert lock on table"), errdetail("seq rel name: %s", seq_rel_name))); snprintf(qbuf, sizeof(qbuf), "SELECT 1 FROM %s FOR UPDATE", seq_rel_name); } @@ -2659,6 +2747,7 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend else { POOL_SELECT_RESULT *result; + /* issue row lock command */ do_query(MASTER(backend), qbuf, &result, MAJOR(backend)); if (status == POOL_CONTINUE) @@ -2680,9 +2769,9 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend if (!(result && result->data[0] && !strcmp(result->data[0], "1"))) ereport(FATAL, - (return_code(2), + (return_code(2), errmsg("failed to get insert lock"), - errdetail("unexpected data from backend"))); + errdetail("unexpected data from backend"))); } } } @@ -2718,7 +2807,7 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend else if (status == POOL_DEADLOCK) deadlock_detected = 1; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { @@ -2745,8 +2834,9 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend else if (lock_kind == 2) { POOL_SELECT_RESULT *result; + per_node_statement_log(backend, i, qbuf); - do_query(CONNECTION(backend,i), qbuf, &result, MAJOR(backend)); + do_query(CONNECTION(backend, i), qbuf, &result, MAJOR(backend)); } } @@ -2763,14 +2853,15 @@ POOL_STATUS insert_lock(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend /* * Judge if we have insert_lock table or not. */ -static bool pool_has_insert_lock(void) +static bool +pool_has_insert_lock(void) { /* * Query to know if insert_lock table exists. */ - bool result; - static POOL_RELCACHE *relcache; + bool result; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; backend = pool_get_session_context(false)->backend; @@ -2781,13 +2872,13 @@ static bool pool_has_insert_lock(void) int_register_func, int_unregister_func, false); if (relcache == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to get insert lock status"), - errdetail("error while creating relcache"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to get insert lock status"), + errdetail("error while creating relcache"))); } - result = pool_search_relcache(relcache, backend, "insert_lock")==0?0:1; + result = pool_search_relcache(relcache, backend, "insert_lock") == 0 ? 0 : 1; return result; } @@ -2798,36 +2889,39 @@ static bool pool_has_insert_lock(void) * Return POOL_CONTINUE if the row is inserted successfully * or the row already exists, the others return POOL_ERROR. */ -static POOL_STATUS add_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char* table) +static POOL_STATUS add_lock_target(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *table) { - /* lock the row where reloid is 0 to avoid "duplicate key violates..." error when insert new oid */ + /* + * lock the row where reloid is 0 to avoid "duplicate key violates..." + * error when insert new oid + */ if (!has_lock_target(frontend, backend, NULL, true)) { - ereport(LOG, - (errmsg("add lock target: not lock the row where reloid is 0"))); + ereport(LOG, + (errmsg("add lock target: not lock the row where reloid is 0"))); per_node_statement_log(backend, MASTER_NODE_ID, "LOCK TABLE pgpool_catalog.insert_lock IN SHARE ROW EXCLUSIVE MODE"); - if(do_command(frontend, MASTER(backend), "LOCK TABLE pgpool_catalog.insert_lock IN SHARE ROW EXCLUSIVE MODE", - PROTO_MAJOR_V3, MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) - ereport(ERROR, - (errmsg("unable to add lock target"), - errdetail("do_command returned DEADLOCK status"))); - - if (has_lock_target(frontend, backend, NULL, false)) - { - ereport(DEBUG1, - (errmsg("add lock target: reloid 0 already exists in insert_lock table"))); - } - else - { - if (insert_oid_into_insert_lock(frontend, backend, NULL) != POOL_CONTINUE) - { - ereport(ERROR, - (errmsg("unable to start the internal transaction"), - errdetail("failed to insert 0 into insert_lock table"))); - } - } + if (do_command(frontend, MASTER(backend), "LOCK TABLE pgpool_catalog.insert_lock IN SHARE ROW EXCLUSIVE MODE", + PROTO_MAJOR_V3, MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) + ereport(ERROR, + (errmsg("unable to add lock target"), + errdetail("do_command returned DEADLOCK status"))); + + if (has_lock_target(frontend, backend, NULL, false)) + { + ereport(DEBUG1, + (errmsg("add lock target: reloid 0 already exists in insert_lock table"))); + } + else + { + if (insert_oid_into_insert_lock(frontend, backend, NULL) != POOL_CONTINUE) + { + ereport(ERROR, + (errmsg("unable to start the internal transaction"), + errdetail("failed to insert 0 into insert_lock table"))); + } + } } /* does insert_lock table contain the oid of the table? */ @@ -2841,9 +2935,9 @@ static POOL_STATUS add_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_PO /* insert the oid of the table into insert_lock table */ if (insert_oid_into_insert_lock(frontend, backend, table) != POOL_CONTINUE) - ereport(ERROR, - (errmsg("unable to start the internal transaction"), - errdetail("could not insert \"%s\" oid into insert_lock table", table))); + ereport(ERROR, + (errmsg("unable to start the internal transaction"), + errdetail("could not insert \"%s\" oid into insert_lock table", table))); return POOL_CONTINUE; @@ -2854,12 +2948,13 @@ static POOL_STATUS add_lock_target(POOL_CONNECTION *frontend, POOL_CONNECTION_PO * If the table name is NULL, this function checks whether oid 0 exists. * If lock is true, this function locks the row of the table oid. */ -static bool has_lock_target(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - char* table, bool lock) +static bool +has_lock_target(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + char *table, bool lock) { - char *suffix; - char qbuf[QUERY_STRING_BUFFER_LEN]; + char *suffix; + char qbuf[QUERY_STRING_BUFFER_LEN]; POOL_SELECT_RESULT *result; suffix = lock ? " FOR UPDATE" : ""; @@ -2895,11 +2990,11 @@ static bool has_lock_target(POOL_CONNECTION *frontend, /* * Insert the oid of the specified table into insert_lock table. */ -static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - char* table) +static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + char *table) { - char qbuf[QUERY_STRING_BUFFER_LEN]; + char qbuf[QUERY_STRING_BUFFER_LEN]; POOL_STATUS status; if (table) @@ -2927,11 +3022,12 @@ static POOL_STATUS insert_oid_into_insert_lock(POOL_CONNECTION *frontend, * The table name is stored in the static buffer of this function. * So subsequent call to this function will destroy previous result. */ -static char *get_insert_command_table_name(InsertStmt *node) +static char * +get_insert_command_table_name(InsertStmt *node) { POOL_SESSION_CONTEXT *session_context; - static char table[MAX_NAME_LEN+1]; - char *p; + static char table[MAX_NAME_LEN + 1]; + char *p; session_context = pool_get_session_context(true); if (!session_context) @@ -2946,12 +3042,13 @@ static char *get_insert_command_table_name(InsertStmt *node) strlcpy(table, p, sizeof(table)); ereport(DEBUG2, - (errmsg("table name in insert command is \"%s\"", table))); + (errmsg("table name in insert command is \"%s\"", table))); return table; } /* judge if this is a DROP DATABASE command */ -int is_drop_database(Node *node) +int +is_drop_database(Node *node) { return (node && IsA(node, DropdbStmt)) ? 1 : 0; } @@ -2959,18 +3056,19 @@ int is_drop_database(Node *node) /* * check if any pending data remains in backend. */ -bool is_backend_cache_empty(POOL_CONNECTION_POOL *backend) +bool +is_backend_cache_empty(POOL_CONNECTION_POOL * backend) { - int i; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; /* - * If SSL is enabled, we need to check SSL internal buffer - * is empty or not first. + * If SSL is enabled, we need to check SSL internal buffer is empty or + * not first. */ if (pool_ssl_pending(CONNECTION(backend, i))) return false; @@ -2985,11 +3083,12 @@ bool is_backend_cache_empty(POOL_CONNECTION_POOL *backend) /* * check if any pending data remains. */ -static bool is_cache_empty(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +static bool +is_cache_empty(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { /* - * If SSL is enabled, we need to check SSL internal buffer - * is empty or not first. + * If SSL is enabled, we need to check SSL internal buffer is empty or not + * first. */ if (pool_ssl_pending(frontend)) return false; @@ -3003,15 +3102,17 @@ static bool is_cache_empty(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *back /* * check if query is needed to wait completion */ -bool is_strict_query(Node *node) +bool +is_strict_query(Node *node) { switch (node->type) { case T_SelectStmt: - { - SelectStmt *stmt = (SelectStmt *)node; - return stmt->intoClause != NULL|| stmt->lockingClause != NIL; - } + { + SelectStmt *stmt = (SelectStmt *) node; + + return stmt->intoClause != NULL || stmt->lockingClause != NIL; + } case T_UpdateStmt: case T_InsertStmt: @@ -3026,7 +3127,8 @@ bool is_strict_query(Node *node) return false; } -int check_copy_from_stdin(Node *node) +int +check_copy_from_stdin(Node *node) { if (copy_schema) pfree(copy_schema); @@ -3039,40 +3141,41 @@ int check_copy_from_stdin(Node *node) if (IsA(node, CopyStmt)) { - CopyStmt *stmt = (CopyStmt *)node; + CopyStmt *stmt = (CopyStmt *) node; + if (stmt->is_from == TRUE && stmt->filename == NULL) { - RangeVar *relation = (RangeVar *)stmt->relation; - ListCell *lc; + RangeVar *relation = (RangeVar *) stmt->relation; + ListCell *lc; /* query is COPY FROM STDIN */ if (relation->schemaname) - copy_schema = MemoryContextStrdup(TopMemoryContext,relation->schemaname); + copy_schema = MemoryContextStrdup(TopMemoryContext, relation->schemaname); else - copy_schema = MemoryContextStrdup(TopMemoryContext,"public"); + copy_schema = MemoryContextStrdup(TopMemoryContext, "public"); - copy_table = MemoryContextStrdup(TopMemoryContext,relation->relname); + copy_table = MemoryContextStrdup(TopMemoryContext, relation->relname); - copy_delimiter = '\t'; /* default delimiter */ - copy_null = MemoryContextStrdup(TopMemoryContext,"\\N"); /* default null string */ + copy_delimiter = '\t'; /* default delimiter */ + copy_null = MemoryContextStrdup(TopMemoryContext, "\\N"); /* default null string */ /* look up delimiter and null string. */ - foreach (lc, stmt->options) + foreach(lc, stmt->options) { - DefElem *elem = lfirst(lc); - Value *v; + DefElem *elem = lfirst(lc); + Value *v; if (strcmp(elem->defname, "delimiter") == 0) { - v = (Value *)elem->arg; + v = (Value *) elem->arg; copy_delimiter = v->val.str[0]; } else if (strcmp(elem->defname, "null") == 0) { if (copy_null) pfree(copy_null); - v = (Value *)elem->arg; - copy_null = MemoryContextStrdup(TopMemoryContext,v->val.str); + v = (Value *) elem->arg; + copy_null = MemoryContextStrdup(TopMemoryContext, v->val.str); } } } @@ -3085,32 +3188,35 @@ int check_copy_from_stdin(Node *node) /* * read kind from one backend */ -void read_kind_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *kind, int node) +void +read_kind_from_one_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *kind, int node) { if (VALID_BACKEND(node)) { - char k; + char k; + pool_read(CONNECTION(backend, node), &k, 1); *kind = k; } else { pool_dump_valid_backend(node); - ereport(ERROR, - (errmsg("unable to read message kind from backend"), - errdetail("%d th backend is not valid", node))); + ereport(ERROR, + (errmsg("unable to read message kind from backend"), + errdetail("%d th backend is not valid", node))); } } /* * returns true if all slaves status are 'C' (Command Complete) */ -static bool is_all_slaves_command_complete(unsigned char *kind_list, int num_backends, int master) +static bool +is_all_slaves_command_complete(unsigned char *kind_list, int num_backends, int master) { - int i; - int ok = true; + int i; + int ok = true; - for (i=0;i<num_backends;i++) + for (i = 0; i < num_backends; i++) { if (i == master || kind_list[i] == 0) continue; @@ -3129,26 +3235,29 @@ static bool is_all_slaves_command_complete(unsigned char *kind_list, int num_bac * the out parameter "decided_kind" is the packet kind decided by this function. * this function uses "decide by majority" method if kinds from all backends do not agree. */ -void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, char *decided_kind) +void +read_kind_from_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, char *decided_kind) { - int i; + int i; unsigned char kind_list[MAX_NUM_BACKENDS]; /* records each backend's kind */ - unsigned char kind_map[256]; /* records which kind gets majority. - * 256 is the number of distinct values expressed by unsigned char - */ + unsigned char kind_map[256]; /* records which kind gets majority. 256 + * is the number of distinct values + * expressed by unsigned char */ unsigned char kind; - int trust_kind = 0; /* decided kind */ - int max_kind = 0; - double max_count = 0; - int degenerate_node_num = 0; /* number of backends degeneration requested */ - int degenerate_node[MAX_NUM_BACKENDS]; /* degeneration requested backend list */ + int trust_kind = 0; /* decided kind */ + int max_kind = 0; + double max_count = 0; + int degenerate_node_num = 0; /* number of backends degeneration + * requested */ + int degenerate_node[MAX_NUM_BACKENDS]; /* degeneration requested + * backend list */ POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); POOL_QUERY_CONTEXT *query_context = session_context->query_context; POOL_PENDING_MESSAGE *msg = NULL; POOL_PENDING_MESSAGE *previous_message; - int num_executed_nodes = 0; - int first_node = -1; + int num_executed_nodes = 0; + int first_node = -1; memset(kind_map, 0, sizeof(kind_map)); @@ -3163,8 +3272,8 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* * There is no pending message in the queue. This could mean we - * are receiving data rows. If so, previous_msg must exist and the - * query must be SELECT. + * are receiving data rows. If so, previous_msg must exist and + * the query must be SELECT. */ if (previous_message == NULL) { @@ -3176,9 +3285,9 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac else { /* - * Previous message exists. Let's see if it could return - * rows. If not, we cannot predict what kind of message will - * arrive, so just unset query in progress. + * Previous message exists. Let's see if it could return rows. + * If not, we cannot predict what kind of message will arrive, + * so just unset query in progress. */ if (previous_message->is_rows_returned) { @@ -3226,19 +3335,19 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac (errmsg("reading backend data packet kind"), errdetail("master node id: %d", MASTER_NODE_ID))); - read_kind_from_one_backend(frontend, backend, (char *)&kind, MASTER_NODE_ID); + read_kind_from_one_backend(frontend, backend, (char *) &kind, MASTER_NODE_ID); /* - * If we received a notification message in master/slave mode, - * other backends will not receive the message. - * So we should skip other nodes otherwise we will hang in pool_read. + * If we received a notification message in master/slave mode, other + * backends will not receive the message. So we should skip other + * nodes otherwise we will hang in pool_read. */ if (kind == 'A') { *decided_kind = 'A'; ereport(DEBUG5, - (errmsg("reading backend data packet kind"), + (errmsg("reading backend data packet kind"), errdetail("received notification message for master node %d", MASTER_NODE_ID))); @@ -3247,7 +3356,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac pool_unread(CONNECTION(backend, MASTER_NODE_ID), &kind, sizeof(kind)); } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { /* initialize degenerate record */ degenerate_node[i] = 0; @@ -3262,8 +3371,9 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac do { - char *p, *value; - int len; + char *p, + *value; + int len; kind = 0; if (pool_read(CONNECTION(backend, i), &kind, 1)) @@ -3283,8 +3393,8 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac } ereport(DEBUG5, - (errmsg("reading backend data packet kind"), - errdetail("backend:%d kind:'%c'",i, kind))); + (errmsg("reading backend data packet kind"), + errdetail("backend:%d kind:'%c'", i, kind))); /* * Read and discard parameter status and notice messages @@ -3292,7 +3402,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (kind == 'N') { ereport(DEBUG5, - (errmsg("received log message from backend %d while reading packet kind",i))); + (errmsg("received log message from backend %d while reading packet kind", i))); pool_process_notice_message_from_one_backend(frontend, backend, i, kind); } @@ -3305,7 +3415,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac { value = p + strlen(p) + 1; ereport(DEBUG5, - (errmsg("reading backend data packet kind"), + (errmsg("reading backend data packet kind"), errdetail("parameter name: %s value: \"%s\"", p, value))); if (IS_MASTER_NODE_ID(i)) @@ -3314,12 +3424,12 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac else { ereport(WARNING, - (errmsg("failed to read parameter status packet from backend %d", i), + (errmsg("failed to read parameter status packet from backend %d", i), errdetail("read from backend failed"))); } } - } while (kind == 'S' || kind == 'N' ); + } while (kind == 'S' || kind == 'N'); #ifdef DEALLOCATE_ERROR_TEST if (i == 1 && kind == 'C' && @@ -3331,8 +3441,8 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac kind_list[i] = kind; ereport(DEBUG5, - (errmsg("reading backend data packet kind"), - errdetail("backend:%d of %d kind = '%c'", i,NUM_BACKENDS, kind_list[i]))); + (errmsg("reading backend data packet kind"), + errdetail("backend:%d of %d kind = '%c'", i, NUM_BACKENDS, kind_list[i]))); kind_map[kind]++; @@ -3353,7 +3463,8 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (max_count != num_executed_nodes) { /* - * not all backends agree with kind. We need to do "decide by majority" + * not all backends agree with kind. We need to do "decide by + * majority" */ /* @@ -3361,36 +3472,29 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac * query) on master and kind on standby is not 'Z', it is likely that * following scenario happened. * - * FE=>Parse("BEGIN") - * FE=>Bind - * FE=>Execute("BEGIN"); + * FE=>Parse("BEGIN") FE=>Bind FE=>Execute("BEGIN"); * - * At this point, Parse, Bind and Execute message are sent to both primary - * and standby node (if load balancing node is not primary). Then, the - * frontend sends next parse message which is supposed to be executed - * on primary only, for example UPDATE. + * At this point, Parse, Bind and Execute message are sent to both + * primary and standby node (if load balancing node is not primary). + * Then, the frontend sends next parse message which is supposed to be + * executed on primary only, for example UPDATE. * - * FE=>Parse("UPDATE ...") - * FE=>Bind - * FE=>Execute("Update..."); - * FE=>Sync + * FE=>Parse("UPDATE ...") FE=>Bind FE=>Execute("Update..."); FE=>Sync * * Here, Sync message is sent to only primary, since the query context * said so. Thus responses for Parse, Bind, and Execute for "BEGIN" * are still penidng on the standby node. - + * * The the frontend sends closes the transaction. * - * FE=>Parse("COMMIT"); - * FE=>Bind - * FE=>Execute - * FE=>Sync + * FE=>Parse("COMMIT"); FE=>Bind FE=>Execute FE=>Sync * * Here, sync message is sent to both primary and standby. So both * nodes happily send back responses. Those will be: * * On the primary side: parse complete, bind complete, command - * complete and ready for query[1]. These are all responses for COMMIT. + * complete and ready for query[1]. These are all responses for + * COMMIT. * * On the standby side: parse complete, bind complete and command * complete. These are all responses for *BEGIN*. Then parse @@ -3412,8 +3516,8 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac * cases it is possible that similar issue could happen since returned * messages do not follow the sequence recorded in the pending * messages because the backend ignores requests till sync message is - * received. In this case we need to re-sync either master or - * standby. So we check not only the standby but master node. + * received. In this case we need to re-sync either master or standby. + * So we check not only the standby but master node. */ if (session_context->load_balance_node_id != MASTER_NODE_ID && (kind_list[MASTER_NODE_ID] == 'Z' || @@ -3421,8 +3525,8 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac && SL_MODE) { POOL_CONNECTION *s; - char *buf; - int len; + char *buf; + int len; if (kind_list[MASTER_NODE_ID] == 'Z') s = CONNECTION(backend, session_context->load_balance_node_id); @@ -3442,7 +3546,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac ereport(DEBUG5, (errmsg("read_kind_from_backend: skipped first standy packet"))); - for(;;) + for (;;) { pool_read(s, &kind, 1); @@ -3495,13 +3599,13 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac * deferred trigger. */ else if (MASTER_SLAVE && query_context->parse_tree && - is_commit_query(query_context->parse_tree) && - kind_list[MASTER_NODE_ID] == 'E' && - is_all_slaves_command_complete(kind_list, NUM_BACKENDS, MASTER_NODE_ID)) + is_commit_query(query_context->parse_tree) && + kind_list[MASTER_NODE_ID] == 'E' && + is_all_slaves_command_complete(kind_list, NUM_BACKENDS, MASTER_NODE_ID)) { *decided_kind = kind_list[MASTER_NODE_ID]; ereport(LOG, - (errmsg("reading backend data packet kind. Error on master while all slaves are normal"), + (errmsg("reading backend data packet kind. Error on master while all slaves are normal"), errdetail("do not degenerate because it is likely caused by a delayed commit"))); return; @@ -3511,7 +3615,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac /* no one gets majority. We trust master node's kind */ trust_kind = kind_list[MASTER_NODE_ID]; } - else /* max_count > NUM_BACKENDS / 2.0 */ + else /* max_count > NUM_BACKENDS / 2.0 */ { /* trust majority's kind */ trust_kind = max_kind; @@ -3526,17 +3630,17 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac { /* degenerate */ ereport(WARNING, - (errmsg("packet kind of backend %d ['%c'] does not match with master/majority nodes packet kind ['%c']",i,kind_list[i],trust_kind))); + (errmsg("packet kind of backend %d ['%c'] does not match with master/majority nodes packet kind ['%c']", i, kind_list[i], trust_kind))); degenerate_node[degenerate_node_num++] = i; } } } else if (first_node == -1) { - ereport(FATAL, - (return_code(2), - errmsg("failed to read kind from backend"), - errdetail("couldn't find first node. All backend down?"))); + ereport(FATAL, + (return_code(2), + errmsg("failed to read kind from backend"), + errdetail("couldn't find first node. All backend down?"))); } else trust_kind = kind_list[first_node]; @@ -3545,23 +3649,23 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (degenerate_node_num) { - int retcode = 2; - String *msg = init_string("kind mismatch among backends. "); + int retcode = 2; + String *msg = init_string("kind mismatch among backends. "); string_append_char(msg, "Possible last query was: \""); string_append_char(msg, query_string_buffer); string_append_char(msg, "\" kind details are:"); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { - char buf[32]; + char buf[32]; if (kind_list[i]) { if (kind_list[i] == 'E' || kind_list[i] == 'N') { - char *m; + char *m; snprintf(buf, sizeof(buf), " %d[%c: ", i, kind_list[i]); string_append_char(msg, buf); @@ -3578,13 +3682,14 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac } /* - * If the error was caused by DEALLOCATE then print original query + * If the error was caused by DEALLOCATE then print + * original query */ - if (kind_list[i] == 'E') + if (kind_list[i] == 'E') { - List *parse_tree_list; - Node *node; - bool error; + List *parse_tree_list; + Node *node; + bool error; parse_tree_list = raw_parser(query_string_buffer, &error); @@ -3595,7 +3700,7 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (IsA(node, DeallocateStmt)) { POOL_SENT_MESSAGE *sent_msg; - DeallocateStmt *d = (DeallocateStmt *)node; + DeallocateStmt *d = (DeallocateStmt *) node; sent_msg = pool_get_sent_message('Q', d->name, POOL_SENT_MESSAGE_CREATED); if (!sent_msg) @@ -3625,13 +3730,13 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac if (pool_config->replication_stop_on_mismatch) { degenerate_backend_set(degenerate_node, degenerate_node_num, REQ_DETAIL_CONFIRMED); - retcode = 1; + retcode = 1; } - ereport(FATAL, - (return_code(retcode), - errmsg("failed to read kind from backend"), - errdetail("%s",msg->data), - errhint("check data consistency among db nodes"))); + ereport(FATAL, + (return_code(retcode), + errmsg("failed to read kind from backend"), + errdetail("%s", msg->data), + errhint("check data consistency among db nodes"))); } @@ -3691,8 +3796,11 @@ void read_kind_from_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *bac char * parse_copy_data(char *buf, int len, char delimiter, int col_id) { - int i, j, field = 0; - char *str, *p = NULL; + int i, + j, + field = 0; + char *str, + *p = NULL; str = palloc(len + 1); @@ -3702,12 +3810,12 @@ parse_copy_data(char *buf, int len, char delimiter, int col_id) { if (buf[i] == '\\' && i != len - 2) /* escape */ { - if (buf[i+1] == delimiter) + if (buf[i + 1] == delimiter) i++; str[j++] = buf[i]; } - else if (buf[i] == delimiter) /* delimiter */ + else if (buf[i] == delimiter) /* delimiter */ { if (field == col_id) { @@ -3728,11 +3836,11 @@ parse_copy_data(char *buf, int len, char delimiter, int col_id) if (field == col_id) { str[j] = '\0'; - p = palloc(j+1); + p = palloc(j + 1); strcpy(p, str); p[j] = '\0'; ereport(DEBUG1, - (errmsg("parsing copy data"), + (errmsg("parsing copy data"), errdetail("divide key value is %s", p))); } @@ -3740,25 +3848,26 @@ parse_copy_data(char *buf, int len, char delimiter, int col_id) return p; } -void query_ps_status(char *query, POOL_CONNECTION_POOL *backend) +void +query_ps_status(char *query, POOL_CONNECTION_POOL * backend) { StartupPacket *sp; - char psbuf[1024]; - int i = 0; + char psbuf[1024]; + int i = 0; if (*query == '\0') return; sp = MASTER_CONNECTION(backend)->sp; - if(sp) - i = snprintf(psbuf, sizeof(psbuf) - 1, "%s %s %s ", - sp->user, sp->database, remote_ps_data); + if (sp) + i = snprintf(psbuf, sizeof(psbuf) - 1, "%s %s %s ", + sp->user, sp->database, remote_ps_data); /* skip spaces */ while (*query && isspace(*query)) query++; - for (; i< sizeof(psbuf)-1; i++) + for (; i < sizeof(psbuf) - 1; i++) { if (!*query || isspace(*query)) break; @@ -3771,9 +3880,11 @@ void query_ps_status(char *query, POOL_CONNECTION_POOL *backend) } /* compare function for bsearch() */ -int compare(const void *p1, const void *p2) +int +compare(const void *p1, const void *p2) { - int v1, v2; + int v1, + v2; v1 = *(NodeTag *) p1; v2 = *(NodeTag *) p2; @@ -3781,7 +3892,8 @@ int compare(const void *p1, const void *p2) } /* return true if needed to start a transaction for the nodetag */ -static bool is_internal_transaction_needed(Node *node) +static bool +is_internal_transaction_needed(Node *node) { static NodeTag nodemap[] = { T_PlannedStmt, @@ -3793,38 +3905,39 @@ static bool is_internal_transaction_needed(Node *node) T_AlterDomainStmt, T_GrantStmt, T_GrantRoleStmt, + /* - T_AlterDefaultPrivilegesStmt, Our parser does not support yet - */ + * T_AlterDefaultPrivilegesStmt, Our parser does not support yet + */ T_ClosePortalStmt, T_ClusterStmt, T_CopyStmt, - T_CreateStmt, /* CREAE TABLE */ - T_DefineStmt, /* CREATE AGGREGATE, OPERATOR, TYPE */ - T_DropStmt, /* DROP TABLE etc. */ + T_CreateStmt, /* CREAE TABLE */ + T_DefineStmt, /* CREATE AGGREGATE, OPERATOR, TYPE */ + T_DropStmt, /* DROP TABLE etc. */ T_TruncateStmt, T_CommentStmt, T_FetchStmt, - T_IndexStmt, /* CREATE INDEX */ + T_IndexStmt, /* CREATE INDEX */ T_CreateFunctionStmt, T_AlterFunctionStmt, + /* - T_DoStmt, Our parser does not support yet - */ - T_RenameStmt, /* ALTER AGGREGATE etc. */ - T_RuleStmt, /* CREATE RULE */ + * T_DoStmt, Our parser does not support yet + */ + T_RenameStmt, /* ALTER AGGREGATE etc. */ + T_RuleStmt, /* CREATE RULE */ T_NotifyStmt, T_ListenStmt, T_UnlistenStmt, - T_ViewStmt, /* CREATE VIEW */ + T_ViewStmt, /* CREATE VIEW */ T_LoadStmt, T_CreateDomainStmt, + /* - T_CreatedbStmt, CREATE DATABASE/DROP DATABASE cannot execute inside a transaction block - T_DropdbStmt, - T_VacuumStmt, - T_ExplainStmt, - */ + * T_CreatedbStmt, CREATE DATABASE/DROP DATABASE cannot execute inside + * a transaction block T_DropdbStmt, T_VacuumStmt, T_ExplainStmt, + */ T_CreateSeqStmt, T_AlterSeqStmt, T_VariableSetStmt, /* SET */ @@ -3868,19 +3981,20 @@ static bool is_internal_transaction_needed(Node *node) T_CreateUserMappingStmt, T_AlterUserMappingStmt, T_DropUserMappingStmt, + /* - T_AlterTableSpaceOptionsStmt, Our parser does not support yet - */ + * T_AlterTableSpaceOptionsStmt, Our parser does not support yet + */ }; - if (bsearch(&nodeTag(node), nodemap, sizeof(nodemap)/sizeof(nodemap[0]), sizeof(NodeTag), compare) != NULL) + if (bsearch(&nodeTag(node), nodemap, sizeof(nodemap) / sizeof(nodemap[0]), sizeof(NodeTag), compare) != NULL) { /* * Check CREATE INDEX CONCURRENTLY. If so, do not start transaction */ if (IsA(node, IndexStmt)) { - if (((IndexStmt *)node)->concurrent) + if (((IndexStmt *) node)->concurrent) return false; } @@ -3889,17 +4003,18 @@ static bool is_internal_transaction_needed(Node *node) */ else if (IsA(node, ClusterStmt)) { - if (((ClusterStmt *)node)->relation == NULL) + if (((ClusterStmt *) node)->relation == NULL) return false; } /* - * REINDEX DATABASE or SYSTEM cannot be executed in a transaction block + * REINDEX DATABASE or SYSTEM cannot be executed in a transaction + * block */ else if (IsA(node, ReindexStmt)) { - if (((ReindexStmt *)node)->kind == REINDEX_OBJECT_SYSTEM || - ((ReindexStmt *)node)->kind == REINDEX_OBJECT_DATABASE) + if (((ReindexStmt *) node)->kind == REINDEX_OBJECT_SYSTEM || + ((ReindexStmt *) node)->kind == REINDEX_OBJECT_DATABASE) return false; } @@ -3912,16 +4027,17 @@ static bool is_internal_transaction_needed(Node *node) /* * Start an internal transaction if necessary. */ -POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, Node *node) +POOL_STATUS +start_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, Node *node) { - int i; + int i; - /* If we are not in a transaction block, - * start a new transaction + /* + * If we are not in a transaction block, start a new transaction */ if (is_internal_transaction_needed(node)) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !INTERNAL_TRANSACTION_STARTED(backend, i) && TSTATE(backend, i) == 'I') @@ -3929,10 +4045,10 @@ POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTIO per_node_statement_log(backend, i, "BEGIN"); if (do_command(frontend, CONNECTION(backend, i), "BEGIN", MAJOR(backend), - MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) - ereport(ERROR, - (errmsg("unable to start the internal transaction"), - errdetail("do_command returned DEADLOCK status"))); + MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) + ereport(ERROR, + (errmsg("unable to start the internal transaction"), + errdetail("do_command returned DEADLOCK status"))); /* Mark that we started new transaction */ INTERNAL_TRANSACTION_STARTED(backend, i) = true; @@ -3946,98 +4062,99 @@ POOL_STATUS start_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTIO /* * End internal transaction. */ -POOL_STATUS end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +POOL_STATUS +end_internal_transaction(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - int i; - int len; - char tstate; + int i; + int len; + char tstate; pool_sigset_t oldmask; /* - * We must block all signals. If pgpool SIGTERM, SIGINT or SIGQUIT - * is delivered, it could cause data inconsistency. + * We must block all signals. If pgpool SIGTERM, SIGINT or SIGQUIT is + * delivered, it could cause data inconsistency. */ POOL_SETMASK2(&BlockSig, &oldmask); - PG_TRY(); - { - /* We need to commit from secondary to master. */ - for (i=0;i<NUM_BACKENDS;i++) - { - if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i) && - TSTATE(backend, i) != 'I' && - INTERNAL_TRANSACTION_STARTED(backend, i)) - { - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - /* - * Skip rest of Ready for Query packet - */ - pool_read(CONNECTION(backend, i), &len, sizeof(len)); - pool_read(CONNECTION(backend, i), &tstate, sizeof(tstate)); - } - - per_node_statement_log(backend, i, "COMMIT"); - PG_TRY(); - { - if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), - MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 1) != POOL_CONTINUE) - { - ereport(ERROR, + PG_TRY(); + { + /* We need to commit from secondary to master. */ + for (i = 0; i < NUM_BACKENDS; i++) + { + if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i) && + TSTATE(backend, i) != 'I' && + INTERNAL_TRANSACTION_STARTED(backend, i)) + { + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + /* + * Skip rest of Ready for Query packet + */ + pool_read(CONNECTION(backend, i), &len, sizeof(len)); + pool_read(CONNECTION(backend, i), &tstate, sizeof(tstate)); + } + + per_node_statement_log(backend, i, "COMMIT"); + PG_TRY(); + { + if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), + MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 1) != POOL_CONTINUE) + { + ereport(ERROR, + (errmsg("unable to COMMIT the transaction"), + errdetail("do_command returned DEADLOCK status"))); + } + } + PG_CATCH(); + { + INTERNAL_TRANSACTION_STARTED(backend, i) = false; + PG_RE_THROW(); + } + PG_END_TRY(); + + INTERNAL_TRANSACTION_STARTED(backend, i) = false; + } + } + + /* Commit on master */ + if (TSTATE(backend, MASTER_NODE_ID) != 'I' && + INTERNAL_TRANSACTION_STARTED(backend, MASTER_NODE_ID)) + { + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + /* + * Skip rest of Ready for Query packet + */ + pool_read(CONNECTION(backend, MASTER_NODE_ID), &len, sizeof(len)); + pool_read(CONNECTION(backend, MASTER_NODE_ID), &tstate, sizeof(tstate)); + } + + per_node_statement_log(backend, MASTER_NODE_ID, "COMMIT"); + PG_TRY(); + { + if (do_command(frontend, MASTER(backend), "COMMIT", MAJOR(backend), + MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 1) != POOL_CONTINUE) + { + ereport(ERROR, (errmsg("unable to COMMIT the transaction"), - errdetail("do_command returned DEADLOCK status"))); - } - } - PG_CATCH(); - { - INTERNAL_TRANSACTION_STARTED(backend, i) = false; - PG_RE_THROW(); - } - PG_END_TRY(); - - INTERNAL_TRANSACTION_STARTED(backend, i) = false; - } - } - - /* Commit on master */ - if (TSTATE(backend, MASTER_NODE_ID) != 'I' && - INTERNAL_TRANSACTION_STARTED(backend, MASTER_NODE_ID)) - { - if (MAJOR(backend) == PROTO_MAJOR_V3) - { - /* - * Skip rest of Ready for Query packet - */ - pool_read(CONNECTION(backend, MASTER_NODE_ID), &len, sizeof(len)); - pool_read(CONNECTION(backend, MASTER_NODE_ID), &tstate, sizeof(tstate)); - } - - per_node_statement_log(backend, MASTER_NODE_ID, "COMMIT"); - PG_TRY(); - { - if (do_command(frontend, MASTER(backend), "COMMIT", MAJOR(backend), - MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 1) != POOL_CONTINUE) - { - ereport(ERROR, - (errmsg("unable to COMMIT the transaction"), - errdetail("do_command returned DEADLOCK status"))); - } - } - PG_CATCH(); - { - INTERNAL_TRANSACTION_STARTED(backend, MASTER_NODE_ID) = false; - PG_RE_THROW(); - } - PG_END_TRY(); - INTERNAL_TRANSACTION_STARTED(backend, MASTER_NODE_ID) = false; - } - } - PG_CATCH(); - { - POOL_SETMASK(&oldmask); - PG_RE_THROW(); - } - PG_END_TRY(); + errdetail("do_command returned DEADLOCK status"))); + } + } + PG_CATCH(); + { + INTERNAL_TRANSACTION_STARTED(backend, MASTER_NODE_ID) = false; + PG_RE_THROW(); + } + PG_END_TRY(); + INTERNAL_TRANSACTION_STARTED(backend, MASTER_NODE_ID) = false; + } + } + PG_CATCH(); + { + POOL_SETMASK(&oldmask); + PG_RE_THROW(); + } + PG_END_TRY(); POOL_SETMASK(&oldmask); return POOL_CONTINUE; @@ -4046,13 +4163,14 @@ POOL_STATUS end_internal_transaction(POOL_CONNECTION *frontend, POOL_CONNECTION_ /* * Returns true if error message contains PANIC or FATAL. */ -static bool is_panic_or_fatal_error(const char *message, int major) +static bool +is_panic_or_fatal_error(const char *message, int major) { if (major == PROTO_MAJOR_V3) { for (;;) { - char id; + char id; id = *message++; if (id == '\0') @@ -4076,13 +4194,15 @@ static bool is_panic_or_fatal_error(const char *message, int major) return false; } -static int detect_postmaster_down_error(POOL_CONNECTION *backend, int major) +static int +detect_postmaster_down_error(POOL_CONNECTION * backend, int major) { - int r = detect_error(backend, ADMIN_SHUTDOWN_ERROR_CODE, major, 'E', false); + int r = detect_error(backend, ADMIN_SHUTDOWN_ERROR_CODE, major, 'E', false); + if (r < 0) { ereport(DEBUG1, - (errmsg("detecting postmaster down error"))); + (errmsg("detecting postmaster down error"))); return r; } @@ -4094,7 +4214,7 @@ static int detect_postmaster_down_error(POOL_CONNECTION *backend, int major) if (r == SPECIFIED_ERROR) { ereport(DEBUG1, - (errmsg("detecting postmaster down error"), + (errmsg("detecting postmaster down error"), errdetail("receive admin shutdown error from a node"))); return r; } @@ -4114,44 +4234,52 @@ static int detect_postmaster_down_error(POOL_CONNECTION *backend, int major) return r; } -int detect_active_sql_transaction_error(POOL_CONNECTION *backend, int major) +int +detect_active_sql_transaction_error(POOL_CONNECTION * backend, int major) { - int r = detect_error(backend, ACTIVE_SQL_TRANSACTION_ERROR_CODE, major, 'E', true); + int r = detect_error(backend, ACTIVE_SQL_TRANSACTION_ERROR_CODE, major, 'E', true); + if (r == SPECIFIED_ERROR) { ereport(DEBUG1, - (errmsg("detecting active sql transaction error"), + (errmsg("detecting active sql transaction error"), errdetail("receive SET TRANSACTION ISOLATION LEVEL must be called before any query error from a node"))); } return r; } -int detect_deadlock_error(POOL_CONNECTION *backend, int major) +int +detect_deadlock_error(POOL_CONNECTION * backend, int major) { - int r = detect_error(backend, DEADLOCK_ERROR_CODE, major, 'E', true); + int r = detect_error(backend, DEADLOCK_ERROR_CODE, major, 'E', true); + if (r == SPECIFIED_ERROR) ereport(DEBUG1, - (errmsg("detecting deadlock error"), + (errmsg("detecting deadlock error"), errdetail("received deadlock error message from backend"))); return r; } -int detect_serialization_error(POOL_CONNECTION *backend, int major, bool unread) +int +detect_serialization_error(POOL_CONNECTION * backend, int major, bool unread) { - int r = detect_error(backend, SERIALIZATION_FAIL_ERROR_CODE, major, 'E', unread); + int r = detect_error(backend, SERIALIZATION_FAIL_ERROR_CODE, major, 'E', unread); + if (r == SPECIFIED_ERROR) ereport(DEBUG1, - (errmsg("detecting serialization error"), + (errmsg("detecting serialization error"), errdetail("received serialization failure message from backend"))); return r; } -int detect_query_cancel_error(POOL_CONNECTION *backend, int major) +int +detect_query_cancel_error(POOL_CONNECTION * backend, int major) { - int r = detect_error(backend, QUERY_CANCEL_ERROR_CODE, major, 'E', true); + int r = detect_error(backend, QUERY_CANCEL_ERROR_CODE, major, 'E', true); + if (r == SPECIFIED_ERROR) ereport(DEBUG1, - (errmsg("detecting query cancel error"), + (errmsg("detecting query cancel error"), errdetail("received query cancel error message from backend"))); return r; } @@ -4161,13 +4289,16 @@ int detect_query_cancel_error(POOL_CONNECTION *backend, int major) * returns 0 in case of sucess or 1 in cause of specified error. * and throws an ereport for all other errors */ -static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, char class, bool unread) +static int +detect_error(POOL_CONNECTION * backend, char *error_code, int major, char class, bool unread) { - int is_error = 0; - char kind; - int readlen = 0, len; - static char buf[8192]; /* memory space is large enough */ - char *p, *str; + int is_error = 0; + char kind; + int readlen = 0, + len; + static char buf[8192]; /* memory space is large enough */ + char *p, + *str; if (pool_read(backend, &kind, sizeof(kind))) return -1; @@ -4186,7 +4317,7 @@ static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, c /* read actual message */ if (major == PROTO_MAJOR_V3) { - char *e; + char *e; if (pool_read(backend, &len, sizeof(len)) < 0) return -1; @@ -4201,22 +4332,22 @@ static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, c readlen += len; if (readlen >= sizeof(buf)) - ereport(ERROR, - (errmsg("unable to detect error"), - errdetail("not enough space in buffer"))); + ereport(ERROR, + (errmsg("unable to detect error"), + errdetail("not enough space in buffer"))); memcpy(p, str, len); /* - * Checks error code which is formatted 'Cxxxxxx' - * (xxxxxx is error code). + * Checks error code which is formatted 'Cxxxxxx' (xxxxxx is error + * code). */ e = str; while (*e) { if (*e == 'C') - {/* specified error? */ - is_error = (strcmp(e+1, error_code) == 0) ? SPECIFIED_ERROR : 0; + { /* specified error? */ + is_error = (strcmp(e + 1, error_code) == 0) ? SPECIFIED_ERROR : 0; break; } else @@ -4230,9 +4361,9 @@ static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, c readlen += len; if (readlen >= sizeof(buf)) - ereport(ERROR, - (errmsg("unable to detect error"), - errdetail("not enough space in buffer"))); + ereport(ERROR, + (errmsg("unable to detect error"), + errdetail("not enough space in buffer"))); memcpy(p, str, len); } @@ -4252,9 +4383,10 @@ static int detect_error(POOL_CONNECTION *backend, char *error_code, int major, c * pgpool log */ -static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int backend_idx, char kind) +static bool +pool_process_notice_message_from_one_backend(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int backend_idx, char kind) { - int major = MAJOR(backend); + int major = MAJOR(backend); POOL_CONNECTION *backend_conn = CONNECTION(backend, backend_idx); if (kind != 'N') @@ -4263,16 +4395,17 @@ static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION *fronte /* read actual message */ if (major == PROTO_MAJOR_V3) { - char *e; - int len, datalen; - char *buff; - char *errorSev = NULL; - char *errorMsg = NULL; + char *e; + int len, + datalen; + char *buff; + char *errorSev = NULL; + char *errorMsg = NULL; pool_read(backend_conn, &datalen, sizeof(datalen)); len = ntohl(datalen) - 4; - if (len <= 0 ) + if (len <= 0) return false; buff = palloc(len); @@ -4283,24 +4416,25 @@ static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION *fronte while (*e) { - char tok = *e; + char tok = *e; + e++; - if(*e == 0) + if (*e == 0) break; if (tok == 'M') errorMsg = e; - else if(tok == 'S') + else if (tok == 'S') errorSev = e; else e += strlen(e) + 1; - if(errorSev && errorMsg) /* we have all what we need */ + if (errorSev && errorMsg) /* we have all what we need */ break; } /* produce a pgpool log entry */ ereport(LOG, - (errmsg("backend [%d]: %s: %s",backend_idx,errorSev,errorMsg))); + (errmsg("backend [%d]: %s: %s", backend_idx, errorSev, errorMsg))); /* forward it to the frontend */ pool_write(frontend, &kind, 1); pool_write(frontend, &datalen, sizeof(datalen)); @@ -4308,17 +4442,17 @@ static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION *fronte pfree(buff); } - else /* Old Protocol */ + else /* Old Protocol */ { - int len = 0; - char *str = pool_read_string(backend_conn, &len, 0); + int len = 0; + char *str = pool_read_string(backend_conn, &len, 0); if (str == NULL || len <= 0) return false; /* produce a pgpool log entry */ ereport(LOG, - (errmsg("backend [%d]: NOTICE: %s",backend_idx,str))); + (errmsg("backend [%d]: NOTICE: %s", backend_idx, str))); /* forward it to the frontend */ pool_write(frontend, &kind, 1); pool_write_and_flush(frontend, str, len); @@ -4341,91 +4475,93 @@ static bool pool_process_notice_message_from_one_backend(POOL_CONNECTION *fronte * 1: succeeded to extract error message * -1: error */ -int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int major, bool unread, char **message) +int +pool_extract_error_message(bool read_kind, POOL_CONNECTION * backend, int major, bool unread, char **message) { - char kind; - int ret = 1; - int readlen = 0, len; - StringInfo str_buf; /* unread buffer */ - StringInfo str_message_buf; /* message buffer */ + char kind; + int ret = 1; + int readlen = 0, + len; + StringInfo str_buf; /* unread buffer */ + StringInfo str_message_buf; /* message buffer */ MemoryContext oldContext = CurrentMemoryContext; - char *str; + char *str; str_buf = makeStringInfo(); str_message_buf = makeStringInfo(); - PG_TRY(); - { - if (read_kind) - { - len = sizeof(kind); + PG_TRY(); + { + if (read_kind) + { + len = sizeof(kind); - pool_read(backend, &kind, len); + pool_read(backend, &kind, len); - readlen += len; + readlen += len; appendStringInfoChar(str_buf, kind); - if (kind != 'E' && kind != 'N') - { - pool_unread(backend, str_buf->data, readlen); + if (kind != 'E' && kind != 'N') + { + pool_unread(backend, str_buf->data, readlen); pfree(str_message_buf->data); pfree(str_message_buf); pfree(str_buf->data); pfree(str_buf); - ereport(ERROR, - (errmsg("unable to extract error message"), - errdetail("invalid message kind \"%c\"",kind))); - } - } - - /* read actual message */ - if (major == PROTO_MAJOR_V3) - { - char *e; - - pool_read(backend, &len, sizeof(len)); - readlen += sizeof(len); - appendBinaryStringInfo(str_buf, (const char *)&len, sizeof(len)); - - len = ntohl(len) - 4; - str = palloc(len); - - pool_read(backend, str, len); - readlen += len; + ereport(ERROR, + (errmsg("unable to extract error message"), + errdetail("invalid message kind \"%c\"", kind))); + } + } + + /* read actual message */ + if (major == PROTO_MAJOR_V3) + { + char *e; + + pool_read(backend, &len, sizeof(len)); + readlen += sizeof(len); + appendBinaryStringInfo(str_buf, (const char *) &len, sizeof(len)); + + len = ntohl(len) - 4; + str = palloc(len); + + pool_read(backend, str, len); + readlen += len; appendBinaryStringInfo(str_buf, str, len); - /* - * Checks error code which is formatted 'Mxxxxxx' - * (xxxxxx is error message). - */ - e = str; - while (*e) - { - if (*e == 'M') - { - e++; + /* + * Checks error code which is formatted 'Mxxxxxx' (xxxxxx is error + * message). + */ + e = str; + while (*e) + { + if (*e == 'M') + { + e++; appendStringInfoString(str_message_buf, e); - break; - } - else - e = e + strlen(e) + 1; - } - pfree(str); - } - else - { - str = pool_read_string(backend, &len, 0); - readlen += len; + break; + } + else + e = e + strlen(e) + 1; + } + pfree(str); + } + else + { + str = pool_read_string(backend, &len, 0); + readlen += len; appendStringInfoString(str_message_buf, str); - } + } - if (unread) - { - /* Put the message to read buffer */ - pool_unread(backend, str_buf->data, readlen); - } + if (unread) + { + /* Put the message to read buffer */ + pool_unread(backend, str_buf->data, readlen); + } - *message = str_message_buf->data; + *message = str_message_buf->data; pfree(str_message_buf); pfree(str_buf->data); pfree(str_buf); @@ -4443,13 +4579,14 @@ int pool_extract_error_message(bool read_kind, POOL_CONNECTION *backend, int maj /* * read message kind and rest of the packet then discard it */ -POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp) +POOL_STATUS +pool_discard_packet(POOL_CONNECTION_POOL * cp) { - int i; - char kind; + int i; + char kind; POOL_CONNECTION *backend; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) { @@ -4460,8 +4597,8 @@ POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp) pool_read(backend, &kind, sizeof(kind)); - ereport(DEBUG2, - (errmsg("pool_discard_packet: kind: %c", kind))); + ereport(DEBUG2, + (errmsg("pool_discard_packet: kind: %c", kind))); } return pool_discard_packet_contents(cp); @@ -4470,13 +4607,15 @@ POOL_STATUS pool_discard_packet(POOL_CONNECTION_POOL *cp) /* * read message length and rest of the packet then discard it */ -POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp) +POOL_STATUS +pool_discard_packet_contents(POOL_CONNECTION_POOL * cp) { - int len, i; - char *string; + int len, + i; + char *string; POOL_CONNECTION *backend; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) { @@ -4491,18 +4630,18 @@ POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp) len = ntohl(len) - 4; string = pool_read2(backend, len); if (string == NULL) - ereport(ERROR, - (errmsg("pool discard packet contents failed"), - errdetail("error while reading rest of message"))); + ereport(ERROR, + (errmsg("pool discard packet contents failed"), + errdetail("error while reading rest of message"))); } else { string = pool_read_string(backend, &len, 0); if (string == NULL) - ereport(ERROR, - (errmsg("pool discard packet contents failed"), - errdetail("error while reading rest of message"))); + ereport(ERROR, + (errmsg("pool discard packet contents failed"), + errdetail("error while reading rest of message"))); } } return POOL_CONTINUE; @@ -4511,24 +4650,25 @@ POOL_STATUS pool_discard_packet_contents(POOL_CONNECTION_POOL *cp) /* * Read packet from either frontend or backend and process it. */ -static POOL_STATUS read_packets_and_process(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int reset_request, int *state, short *num_fields, bool *cont) +static POOL_STATUS read_packets_and_process(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int reset_request, int *state, short *num_fields, bool *cont) { - fd_set readmask; - fd_set writemask; - fd_set exceptmask; - int fds; + fd_set readmask; + fd_set writemask; + fd_set exceptmask; + int fds; struct timeval timeoutdata; struct timeval *timeout; - int num_fds, was_error = 0; + int num_fds, + was_error = 0; POOL_STATUS status; - int i; + int i; /* - * frontend idle counters. depends on the following - * select(2) call's time out is 1 second. + * frontend idle counters. depends on the following select(2) call's time + * out is 1 second. */ - int idle_count = 0; /* for other than in recovery */ - int idle_count_in_recovery = 0; /* for in recovery */ + int idle_count = 0; /* for other than in recovery */ + int idle_count_in_recovery = 0; /* for in recovery */ SELECT_RETRY: FD_ZERO(&readmask); @@ -4545,29 +4685,29 @@ SELECT_RETRY: } /* - * If we are in load balance mode and the selected node is - * down, we need to re-select load_balancing_node. Note - * that we cannnot use VALID_BACKEND macro here. If - * in_load_balance == 1, VALID_BACKEND macro may return 0. + * If we are in load balance mode and the selected node is down, we need + * to re-select load_balancing_node. Note that we cannnot use + * VALID_BACKEND macro here. If in_load_balance == 1, VALID_BACKEND macro + * may return 0. */ if (pool_config->load_balance_mode && BACKEND_INFO(backend->info->load_balancing_node).backend_status == CON_DOWN) { /* select load balancing node */ POOL_SESSION_CONTEXT *session_context; - int node_id; + int node_id; session_context = pool_get_session_context(false); node_id = select_load_balancing_node(); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { pool_coninfo(session_context->process_context->proc_id, pool_pool_index(), i)->load_balancing_node = node_id; } } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -4598,9 +4738,9 @@ SELECT_RETRY: if (errno == EINTR) goto SELECT_RETRY; - ereport(FATAL, - (errmsg("unable to read data"), - errdetail("select() system call failed with reason \"%s\"",strerror(errno)))); + ereport(FATAL, + (errmsg("unable to read data"), + errdetail("select() system call failed with reason \"%s\"", strerror(errno)))); } /* select timeout */ @@ -4612,12 +4752,12 @@ SELECT_RETRY: if (idle_count > pool_config->client_idle_limit) { - ereport(FRONTEND_ERROR, - (pool_error_code("57000"), - errmsg("unable to read data"), - errdetail("child connection forced to terminate due to client_idle_limit:%d is reached", -pool_config->client_idle_limit))); - } + ereport(FRONTEND_ERROR, + (pool_error_code("57000"), + errmsg("unable to read data"), + errdetail("child connection forced to terminate due to client_idle_limit:%d is reached", + pool_config->client_idle_limit))); + } } else if (*InRecovery > RECOVERY_INIT && pool_config->client_idle_limit_in_recovery > 0) { @@ -4625,22 +4765,22 @@ pool_config->client_idle_limit))); if (idle_count_in_recovery > pool_config->client_idle_limit_in_recovery) { - ereport(FRONTEND_ERROR, - (pool_error_code("57000"), - errmsg("unable to read data"), - errdetail("child connection forced to terminate due to client_idle_limit_in_recovery:%d is reached",pool_config->client_idle_limit_in_recovery))); + ereport(FRONTEND_ERROR, + (pool_error_code("57000"), + errmsg("unable to read data"), + errdetail("child connection forced to terminate due to client_idle_limit_in_recovery:%d is reached", pool_config->client_idle_limit_in_recovery))); } } else if (*InRecovery > RECOVERY_INIT && pool_config->client_idle_limit_in_recovery == -1) { /* - * If we are in recovery and client_idle_limit_in_recovery is -1, then - * exit immediately. + * If we are in recovery and client_idle_limit_in_recovery is -1, + * then exit immediately. */ - ereport(FRONTEND_ERROR, - (pool_error_code("57000"), - errmsg("connection terminated due to online recovery"), - errdetail("child connection forced to terminate due to client_idle_limitis:-1"))); + ereport(FRONTEND_ERROR, + (pool_error_code("57000"), + errmsg("connection terminated due to online recovery"), + errdetail("child connection forced to terminate due to client_idle_limitis:-1"))); } goto SELECT_RETRY; } @@ -4655,27 +4795,28 @@ pool_config->client_idle_limit))); if (CONNECTION_SLOT(backend, i) == 0) { ereport(LOG, - (errmsg("error occured while reading and processing packets"), - errdetail("FATAL ERROR: VALID_BACKEND returns non 0 but connection slot is empty. backend id:%d RAW_MODE:%d LOAD_BALANCE_STATUS:%d status:%d", - i, RAW_MODE, LOAD_BALANCE_STATUS(i), BACKEND_INFO(i).backend_status))); + (errmsg("error occured while reading and processing packets"), + errdetail("FATAL ERROR: VALID_BACKEND returns non 0 but connection slot is empty. backend id:%d RAW_MODE:%d LOAD_BALANCE_STATUS:%d status:%d", + i, RAW_MODE, LOAD_BALANCE_STATUS(i), BACKEND_INFO(i).backend_status))); was_error = 1; break; } if (FD_ISSET(CONNECTION(backend, i)->fd, &readmask)) { - int r; + int r; + /* * connection was terminated due to confilct with recovery */ r = detect_serialization_error(CONNECTION(backend, i), MAJOR(backend), false); if (r == SPECIFIED_ERROR) { - ereport(FATAL, - (pool_error_code(SERIALIZATION_FAIL_ERROR_CODE), - errmsg("connection was terminated due to conflict with recovery"), - errdetail("User was holding a relation lock for too long."), - errhint("In a moment you should be able to reconnect to the database and repeat your command."))); + ereport(FATAL, + (pool_error_code(SERIALIZATION_FAIL_ERROR_CODE), + errmsg("connection was terminated due to conflict with recovery"), + errdetail("User was holding a relation lock for too long."), + errhint("In a moment you should be able to reconnect to the database and repeat your command."))); } @@ -4686,7 +4827,7 @@ pool_config->client_idle_limit))); if (r == SPECIFIED_ERROR) { ereport(LOG, - (errmsg("reading and processing packets"), + (errmsg("reading and processing packets"), errdetail("postmaster on DB node %d was shutdown by administrative command", i))); /* @@ -4700,11 +4841,15 @@ pool_config->client_idle_limit))); was_error = 1; if (!VALID_BACKEND(i)) break; - /* check if the pg_terminate_backend was issued on this connection */ + + /* + * check if the pg_terminate_backend was issued on + * this connection + */ if (CONNECTION(backend, i)->con_info->swallow_termination == 1) { ereport(FATAL, - (errmsg("connection to postmaster on DB node %d was lost due to pg_terminate_backend", i), + (errmsg("connection to postmaster on DB node %d was lost due to pg_terminate_backend", i), errdetail("pg_terminate_backend was called on the backend"))); } else @@ -4726,14 +4871,15 @@ pool_config->client_idle_limit))); else if (r < 0) { /* - * This could happen after detecting backend errors and before actually - * detaching the backend. In this case reading from backend socket will - * return EOF and it's better to close this session. So returns POOL_END. + * This could happen after detecting backend errors and + * before actually detaching the backend. In this case + * reading from backend socket will return EOF and it's + * better to close this session. So returns POOL_END. */ - ereport(LOG, - (errmsg("unable to read and process data"), - errdetail("detect_postmaster_down_error returns error on backend %d. Going to close this session.", i))); - return POOL_END; + ereport(LOG, + (errmsg("unable to read and process data"), + errdetail("detect_postmaster_down_error returns error on backend %d. Going to close this session.", i))); + return POOL_END; } } } @@ -4748,9 +4894,9 @@ pool_config->client_idle_limit))); if (!reset_request) { if (FD_ISSET(frontend->fd, &exceptmask)) - ereport(ERROR, - (errmsg("unable to read from frontend socket"), - errdetail("exception occured on frontend socket"))); + ereport(ERROR, + (errmsg("unable to read from frontend socket"), + errdetail("exception occured on frontend socket"))); else if (FD_ISSET(frontend->fd, &readmask)) { @@ -4761,9 +4907,9 @@ pool_config->client_idle_limit))); } if (FD_ISSET(MASTER(backend)->fd, &exceptmask)) - ereport(FATAL, - (errmsg("unable to read from backend socket"), - errdetail("exception occured on backend socket"))); + ereport(FATAL, + (errmsg("unable to read from backend socket"), + errdetail("exception occured on backend socket"))); else if (FD_ISSET(MASTER(backend)->fd, &readmask)) { @@ -4777,12 +4923,13 @@ pool_config->client_idle_limit))); /* * Debugging aid for VALID_BACKEND macro. */ -void pool_dump_valid_backend(int backend_id) +void +pool_dump_valid_backend(int backend_id) { - ereport(LOG, - (errmsg("RAW_MODE:%d REAL_MASTER_NODE_ID:%d pool_is_node_to_be_sent_in_current_query:%d my_backend_status:%d", - RAW_MODE, REAL_MASTER_NODE_ID, pool_is_node_to_be_sent_in_current_query(backend_id), - *my_backend_status[backend_id]))); + ereport(LOG, + (errmsg("RAW_MODE:%d REAL_MASTER_NODE_ID:%d pool_is_node_to_be_sent_in_current_query:%d my_backend_status:%d", + RAW_MODE, REAL_MASTER_NODE_ID, pool_is_node_to_be_sent_in_current_query(backend_id), + *my_backend_status[backend_id]))); } /* @@ -4790,12 +4937,13 @@ void pool_dump_valid_backend(int backend_id) * Should be used for streaming replication mode and extended query. * Returns true if data was actually pushed. */ -bool pool_push_pending_data(POOL_CONNECTION *backend) +bool +pool_push_pending_data(POOL_CONNECTION * backend) { POOL_SESSION_CONTEXT *session_context; - int len; - bool data_pushed = false; - bool pending_data_existed = false; + int len; + bool data_pushed = false; + bool pending_data_existed = false; static char random_statement[] = "pgpool_non_existent"; if (!pool_get_session_context(true) || !pool_is_doing_extended_query_message()) @@ -4820,7 +4968,7 @@ bool pool_push_pending_data(POOL_CONNECTION *backend) * preserves the user's expectation of packet sequence. */ pool_write(backend, "C", 1); - len = htonl(sizeof(len)+1+sizeof(random_statement)); + len = htonl(sizeof(len) + 1 + sizeof(random_statement)); pool_write(backend, &len, sizeof(len)); pool_write(backend, "S", 1); pool_write(backend, random_statement, sizeof(random_statement)); @@ -4831,10 +4979,10 @@ bool pool_push_pending_data(POOL_CONNECTION *backend) (errmsg("pool_push_pending_data: send flush message to %d", backend->db_node_id))); /* - * If we have not send the flush message to load balance node yet, - * send a flush message to the load balance node. Otherwise only - * the non load balance node (usually the master node) produces - * response if we do not send sync message to it yet. + * If we have not send the flush message to load balance node yet, send a + * flush message to the load balance node. Otherwise only the non load + * balance node (usually the master node) produces response if we do not + * send sync message to it yet. */ session_context = pool_get_session_context(false); @@ -4850,12 +4998,12 @@ bool pool_push_pending_data(POOL_CONNECTION *backend) (errmsg("pool_push_pending_data: send flush message to %d", con->db_node_id))); } - for(;;) + for (;;) { - int len; - int len_save; - char *buf; - char kind; + int len; + int len_save; + char *buf; + char kind; pool_set_timeout(-1); diff --git a/src/protocol/pool_proto2.c b/src/protocol/pool_proto2.c index 1f61ac342..0ecc84958 100644 --- a/src/protocol/pool_proto2.c +++ b/src/protocol/pool_proto2.c @@ -1,8 +1,8 @@ /* -*-pgsql-c-*- */ /* * $Header$ - * - * pgpool: a language independent connection pool server for PostgreSQL + * + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2010 PgPool Global Development Group @@ -33,21 +33,26 @@ #include "utils/pool_stream.h" #include "utils/elog.h" -POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short num_fields) +POOL_STATUS +AsciiRow(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + short num_fields) { - static char nullmap[8192], nullmap1[8192]; - int nbytes; - int i, j; + static char nullmap[8192], + nullmap1[8192]; + int nbytes; + int i, + j; unsigned char mask; - int size, size1 = 0; - char *buf = NULL, *sendbuf = NULL; - char msgbuf[1024]; + int size, + size1 = 0; + char *buf = NULL, + *sendbuf = NULL; + char msgbuf[1024]; pool_write(frontend, "D", 1); - nbytes = (num_fields + 7)/8; + nbytes = (num_fields + 7) / 8; if (nbytes <= 0) return POOL_CONTINUE; @@ -55,20 +60,21 @@ POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, /* NULL map */ pool_read(MASTER(backend), nullmap, nbytes); memcpy(nullmap1, nullmap, nbytes); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { pool_read(CONNECTION(backend, i), nullmap, nbytes); if (memcmp(nullmap, nullmap1, nbytes)) { - /* XXX: NULLMAP maybe different among - backends. If we were a paranoid, we have to treat - this as a fatal error. However in the real world - we'd better to adapt this situation. Just throw a - log... */ + /* + * XXX: NULLMAP maybe different among backends. If we were a + * paranoid, we have to treat this as a fatal error. However + * in the real world we'd better to adapt this situation. Just + * throw a log... + */ ereport(DEBUG1, - (errmsg("processing ASCII row"), + (errmsg("processing ASCII row"), errdetail("NULLMAP is different between master and backend no %d", i))); } } @@ -79,13 +85,13 @@ POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, mask = 0; - for (i = 0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { if (mask == 0) mask = 0x80; /* NOT NULL? */ - if (mask & nullmap[i/8]) + if (mask & nullmap[i / 8]) { /* field size */ if (pool_read(MASTER(backend), &size, sizeof(int)) < 0) @@ -104,13 +110,13 @@ POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, /* forward to frontend */ pool_write(frontend, &size, sizeof(int)); pool_write(frontend, sendbuf, size1); - snprintf(msgbuf, Min(sizeof(msgbuf), size1+1), "%s", sendbuf); + snprintf(msgbuf, Min(sizeof(msgbuf), size1 + 1), "%s", sendbuf); ereport(DEBUG1, - (errmsg("processing ASCII row"), + (errmsg("processing ASCII row"), errdetail("len: %d data: %s", size1, msgbuf))); - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (VALID_BACKEND(j) && !IS_MASTER_NODE_ID(j)) { @@ -121,14 +127,15 @@ POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, buf = NULL; size = ntohl(size) - 4; - /* XXX: field size maybe different among - backends. If we were a paranoid, we have to treat - this as a fatal error. However in the real world - we'd better to adapt this situation. Just throw a - log... */ + /* + * XXX: field size maybe different among backends. If we + * were a paranoid, we have to treat this as a fatal + * error. However in the real world we'd better to adapt + * this situation. Just throw a log... + */ if (size != size1) ereport(DEBUG1, - (errmsg("processing ASCII row"), + (errmsg("processing ASCII row"), errdetail("size of field no %d does not match between master [size:%d] and backend no %d [size:%d]", i, ntohl(size), j, ntohl(size1)))); @@ -152,20 +159,24 @@ POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short num_fields) +POOL_STATUS +BinaryRow(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + short num_fields) { - static char nullmap[8192], nullmap1[8192]; - int nbytes; - int i, j; + static char nullmap[8192], + nullmap1[8192]; + int nbytes; + int i, + j; unsigned char mask; - int size, size1 = 0; - char *buf = NULL; + int size, + size1 = 0; + char *buf = NULL; pool_write(frontend, "B", 1); - nbytes = (num_fields + 7)/8; + nbytes = (num_fields + 7) / 8; if (nbytes <= 0) return POOL_CONTINUE; @@ -175,20 +186,21 @@ POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, if (pool_write(frontend, nullmap, nbytes) < 0) return POOL_END; memcpy(nullmap1, nullmap, nbytes); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { pool_read(CONNECTION(backend, i), nullmap, nbytes); if (memcmp(nullmap, nullmap1, nbytes)) { - /* XXX: NULLMAP maybe different among - backends. If we were a paranoid, we have to treat - this as a fatal error. However in the real world - we'd better to adapt this situation. Just throw a - log... */ + /* + * XXX: NULLMAP maybe different among backends. If we were a + * paranoid, we have to treat this as a fatal error. However + * in the real world we'd better to adapt this situation. Just + * throw a log... + */ ereport(DEBUG1, - (errmsg("processing binary row"), + (errmsg("processing binary row"), errdetail("NULLMAP is different between master and backend no %d", i))); } } @@ -196,18 +208,18 @@ POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, mask = 0; - for (i = 0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { if (mask == 0) mask = 0x80; /* NOT NULL? */ - if (mask & nullmap[i/8]) + if (mask & nullmap[i / 8]) { /* field size */ if (pool_read(MASTER(backend), &size, sizeof(int)) < 0) return POOL_END; - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (VALID_BACKEND(j) && !IS_MASTER_NODE_ID(j)) { @@ -215,17 +227,18 @@ POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, if (pool_read(CONNECTION(backend, i), &size, sizeof(int)) < 0) return POOL_END; - /* XXX: field size maybe different among - backends. If we were a paranoid, we have to treat - this as a fatal error. However in the real world - we'd better to adapt this situation. Just throw a - log... */ + /* + * XXX: field size maybe different among backends. If we + * were a paranoid, we have to treat this as a fatal + * error. However in the real world we'd better to adapt + * this situation. Just throw a log... + */ if (size != size1) ereport(DEBUG1, - (errmsg("processing binary row"), - errdetail("size of field no %d does not match between master [size:%d] and backend no %d [size:%d]", - i, ntohl(size), j, ntohl(size1)))); - } + (errmsg("processing binary row"), + errdetail("size of field no %d does not match between master [size:%d] and backend no %d [size:%d]", + i, ntohl(size), j, ntohl(size1)))); + } buf = NULL; @@ -258,13 +271,15 @@ POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +CompletedResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - int i; - char *string = NULL; - char *string1 = NULL; - int len, len1 = 0; + int i; + char *string = NULL; + char *string1 = NULL; + int len, + len1 = 0; /* read command tag */ string = pool_read_string(MASTER(backend), &len, 0); @@ -278,7 +293,7 @@ POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, len1 = len; string1 = pstrdup(string); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i) || IS_MASTER_NODE_ID(i)) continue; @@ -286,22 +301,22 @@ POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, /* read command tag */ string = pool_read_string(CONNECTION(backend, i), &len, 0); if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process completed response"), - errdetail("read from backend node %d failed",i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process completed response"), + errdetail("read from backend node %d failed", i))); else if (!strncmp(string, "BEGIN", 5)) TSTATE(backend, i) = 'T'; else if (!strncmp(string, "COMMIT", 6) || !strncmp(string, "ROLLBACK", 8)) TSTATE(backend, i) = 'I'; - + if (len != len1) { ereport(DEBUG1, - (errmsg("processing completed response"), - errdetail("message length does not match between master(%d \"%s\",) and %d th server (%d \"%s\",)", - len, string, i, len1, string1))); + (errmsg("processing completed response"), + errdetail("message length does not match between master(%d \"%s\",) and %d th server (%d \"%s\",)", + len, string, i, len1, string1))); /* we except INSERT, because INSERT response has OID */ if (strncmp(string1, "INSERT", 6)) @@ -314,7 +329,7 @@ POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, /* forward to the frontend */ pool_write(frontend, "C", 1); ereport(DEBUG2, - (errmsg("processing completed response"), + (errmsg("processing completed response"), errdetail("string: \"%s\"", string1))); pool_write(frontend, string1, len1); @@ -322,13 +337,15 @@ POOL_STATUS CompletedResponse(POOL_CONNECTION *frontend, return pool_flush(frontend); } -POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +CursorResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char *string = NULL; - char *string1 = NULL; - int len, len1 = 0; - int i; + char *string = NULL; + char *string1 = NULL; + int len, + len1 = 0; + int i; /* read cursor name */ string = pool_read_string(MASTER(backend), &len, 0); @@ -337,24 +354,24 @@ POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, len1 = len; string1 = pstrdup(string); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { /* read cursor name */ string = pool_read_string(CONNECTION(backend, i), &len, 0); if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process cursor response"), - errdetail("read failed on backend node %d",i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process cursor response"), + errdetail("read failed on backend node %d", i))); if (len != len1) { - ereport(FATAL, - (return_code(2), - errmsg("unable to process cursor response"), - errdetail("length does not match between master(%d) and %d th backend(%d)",len, i, len1), - errhint("master(%s) %d th backend(%s)", string1, i, string))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process cursor response"), + errdetail("length does not match between master(%d) and %d th backend(%d)", len, i, len1), + errhint("master(%s) %d th backend(%s)", string1, i, string))); } } } @@ -364,17 +381,18 @@ POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, pool_write(frontend, string1, len1); pool_flush(frontend); pfree(string1); - + return POOL_CONTINUE; } -void EmptyQueryResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +void +EmptyQueryResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char c; - int i; + char c; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -386,14 +404,15 @@ void EmptyQueryResponse(POOL_CONNECTION *frontend, pool_write_and_flush(frontend, "", 1); } -POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +ErrorResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char *string = ""; - int len = 0; - int i; + char *string = ""; + int len = 0; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -407,15 +426,15 @@ POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, pool_write(frontend, "E", 1); pool_write_and_flush(frontend, string, len); - /* - * check session context, because this function is called - * by pool_do_auth too. + /* + * check session context, because this function is called by pool_do_auth + * too. */ if (pool_get_session_context(true)) raise_intentional_error_if_need(backend); /* change transaction state */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -427,17 +446,18 @@ POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +FunctionResultResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char dummy; - int len; - char *result = NULL; - int i; + char dummy; + int len; + char *result = NULL; + int i; pool_write(frontend, "V", 1); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -449,7 +469,7 @@ POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, /* non empty result? */ if (dummy == 'G') { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -461,28 +481,28 @@ POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, len = ntohl(len); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { /* result value itself */ if ((result = pool_read2(MASTER(backend), len)) == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process function result response"), - errdetail("reading from backend node %d failed",i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process function result response"), + errdetail("reading from backend node %d failed", i))); } } - if(result) + if (result) pool_write(frontend, result, len); else ereport(FATAL, - (return_code(2), + (return_code(2), errmsg("unable to process function result response"), errdetail("reading from backend node failed"))); } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -495,24 +515,25 @@ POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, return pool_flush(frontend); } -void NoticeResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +void +NoticeResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char *string = NULL; - int len = 0; - int i; + char *string = NULL; + int len = 0; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { /* read notice message */ string = pool_read_string(CONNECTION(backend, i), &len, 0); if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process Notice response"), - errdetail("reading from backend node %d failed",i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process Notice response"), + errdetail("reading from backend node %d failed", i))); } } @@ -520,40 +541,44 @@ void NoticeResponse(POOL_CONNECTION *frontend, pool_write(frontend, "N", 1); if (string == NULL) ereport(FATAL, - (return_code(2), - errmsg("unable to process Notice response"), + (return_code(2), + errmsg("unable to process Notice response"), errdetail("reading from backend node failed"))); else pool_write_and_flush(frontend, string, len); } -POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +NotificationResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - int pid, pid1; - char *condition, *condition1 = NULL; - int len, len1 = 0; - int i; + int pid, + pid1; + char *condition, + *condition1 = NULL; + int len, + len1 = 0; + int i; pool_write(frontend, "A", 1); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { pool_read(CONNECTION(backend, i), &pid, sizeof(pid)); condition = pool_read_string(CONNECTION(backend, i), &len, 0); if (condition == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process Notification response"), - errdetail("reading from backend node %d failed",i))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process Notification response"), + errdetail("reading from backend node %d failed", i))); if (IS_MASTER_NODE_ID(i)) { pid1 = pid; len1 = len; - if(condition1) + if (condition1) pfree(condition1); condition1 = pstrdup(condition); } @@ -566,21 +591,27 @@ POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -int RowDescription(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - short *result) +int +RowDescription(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + short *result) { - short num_fields, num_fields1 = 0; - int oid, mod; - int oid1, mod1; - short size, size1; - char *string; - int len, len1; - int i; + short num_fields, + num_fields1 = 0; + int oid, + mod; + int oid1, + mod1; + short size, + size1; + char *string; + int len, + len1; + int i; pool_read(MASTER(backend), &num_fields, sizeof(short)); num_fields1 = num_fields; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { @@ -588,11 +619,11 @@ int RowDescription(POOL_CONNECTION *frontend, pool_read(CONNECTION(backend, i), &num_fields, sizeof(short)); if (num_fields != num_fields1) { - ereport(FATAL, - (return_code(2), - errmsg("unable to process row description"), - errdetail("num_fields does not match between backends master(%d) and %d th backend(%d)", - num_fields, i, num_fields1))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process row description"), + errdetail("num_fields does not match between backends master(%d) and %d th backend(%d)", + num_fields, i, num_fields1))); } } } @@ -601,9 +632,9 @@ int RowDescription(POOL_CONNECTION *frontend, pool_write(frontend, "T", 1); pool_write(frontend, &num_fields, sizeof(short)); num_fields = ntohs(num_fields); - for (i = 0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { - int j; + int j; /* field name */ string = pool_read_string(MASTER(backend), &len, 0); @@ -612,24 +643,24 @@ int RowDescription(POOL_CONNECTION *frontend, len1 = len; pool_write(frontend, string, len); - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (VALID_BACKEND(j) && !IS_MASTER_NODE_ID(j)) { string = pool_read_string(CONNECTION(backend, j), &len, 0); if (string == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to process row description"), - errdetail("read failed on backend node %d",j))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process row description"), + errdetail("read failed on backend node %d", j))); if (len != len1) { - ereport(FATAL, - (return_code(2), - errmsg("unable to process row description"), - errdetail("field length does not match between backends master(%d) and %d th backend(%d)", - ntohl(len), j, ntohl(len1)))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process row description"), + errdetail("field length does not match between backends master(%d) and %d th backend(%d)", + ntohl(len), j, ntohl(len1)))); } } } @@ -638,9 +669,9 @@ int RowDescription(POOL_CONNECTION *frontend, pool_read(MASTER(backend), &oid, sizeof(int)); oid1 = oid; ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), + (errmsg("processing ROW DESCRIPTION"), errdetail("type oid: %d", ntohl(oid)))); - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (VALID_BACKEND(j) && !IS_MASTER_NODE_ID(j)) { @@ -650,9 +681,9 @@ int RowDescription(POOL_CONNECTION *frontend, if (oid != oid1) { ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("field oid does not match between backends master(%d) and %d th backend(%d)", - ntohl(oid), j, ntohl(oid1)))); + (errmsg("processing ROW DESCRIPTION"), + errdetail("field oid does not match between backends master(%d) and %d th backend(%d)", + ntohl(oid), j, ntohl(oid1)))); } } } @@ -661,32 +692,32 @@ int RowDescription(POOL_CONNECTION *frontend, /* size */ pool_read(MASTER(backend), &size, sizeof(short)); size1 = size; - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (VALID_BACKEND(j) && !IS_MASTER_NODE_ID(j)) { pool_read(CONNECTION(backend, j), &size, sizeof(short)); if (size1 != size) { - ereport(FATAL, - (errmsg("data among backends are different"), - errdetail("field size does not match between backends master(%d) and %d th backend(%d", ntohs(size), j, ntohs(size1)))); + ereport(FATAL, + (errmsg("data among backends are different"), + errdetail("field size does not match between backends master(%d) and %d th backend(%d", ntohs(size), j, ntohs(size1)))); } } } ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), + (errmsg("processing ROW DESCRIPTION"), errdetail("field size: %d", ntohs(size)))); pool_write(frontend, &size1, sizeof(short)); /* modifier */ pool_read(MASTER(backend), &mod, sizeof(int)); ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), + (errmsg("processing ROW DESCRIPTION"), errdetail("modifier: %d", ntohs(mod)))); mod1 = mod; - for (j=0;j<NUM_BACKENDS;j++) + for (j = 0; j < NUM_BACKENDS; j++) { if (VALID_BACKEND(j) && !IS_MASTER_NODE_ID(j)) { @@ -694,9 +725,9 @@ int RowDescription(POOL_CONNECTION *frontend, if (mod != mod1) { ereport(DEBUG1, - (errmsg("processing ROW DESCRIPTION"), - errdetail("modifier does not match between backends master(%d) and %d th backend(%d)", - ntohl(mod), j, ntohl(mod1)))); + (errmsg("processing ROW DESCRIPTION"), + errdetail("modifier does not match between backends master(%d) and %d th backend(%d)", + ntohl(mod), j, ntohl(mod1)))); } } } diff --git a/src/protocol/pool_proto_modules.c b/src/protocol/pool_proto_modules.c index 0ef7de64c..ccaaec02a 100644 --- a/src/protocol/pool_proto_modules.c +++ b/src/protocol/pool_proto_modules.c @@ -59,10 +59,10 @@ #include "utils/memutils.h" #include "pool_config_variables.h" -char *copy_table = NULL; /* copy table name */ -char *copy_schema = NULL; /* copy table name */ -char copy_delimiter; /* copy delimiter char */ -char *copy_null = NULL; /* copy null string */ +char *copy_table = NULL; /* copy table name */ +char *copy_schema = NULL; /* copy table name */ +char copy_delimiter; /* copy delimiter char */ +char *copy_null = NULL; /* copy null string */ /* * Non 0 if allow to close internal transaction. This variable was @@ -70,33 +70,33 @@ char *copy_null = NULL; /* copy null string */ * Sync message is received after receiving Parse message. This hack * is for PHP-PDO. */ -static int allow_close_transaction = 1; +static int allow_close_transaction = 1; -int is_select_pgcatalog = 0; -int is_select_for_update = 0; /* 1 if SELECT INTO or SELECT FOR UPDATE */ +int is_select_pgcatalog = 0; +int is_select_for_update = 0; /* 1 if SELECT INTO or SELECT FOR + * UPDATE */ /* * last query string sent to simpleQuery() */ -char query_string_buffer[QUERY_STRING_BUFFER_LEN]; +char query_string_buffer[QUERY_STRING_BUFFER_LEN]; -static int check_errors(POOL_CONNECTION_POOL *backend, int backend_id); +static int check_errors(POOL_CONNECTION_POOL * backend, int backend_id); static void generate_error_message(char *prefix, int specific_error, char *query); -static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - POOL_SENT_MESSAGE *message, - POOL_SENT_MESSAGE *bind_message); -static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int *number_of_nodes); -static POOL_STATUS close_standby_transactions(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); - -static char * -flatten_set_variable_args(const char *name, List *args); +static POOL_STATUS parse_before_bind(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + POOL_SENT_MESSAGE * message, + POOL_SENT_MESSAGE * bind_message); +static int *find_victim_nodes(int *ntuples, int nmembers, int master_node, int *number_of_nodes); +static POOL_STATUS close_standby_transactions(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); + +static char *flatten_set_variable_args(const char *name, List *args); static bool -process_pg_terminate_backend_func(POOL_QUERY_CONTEXT *query_context); -static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL *backend); -static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend); + process_pg_terminate_backend_func(POOL_QUERY_CONTEXT * query_context); +static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL * backend); +static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend); /* * This is the workhorse of processing the pg_terminate_backend function to @@ -120,32 +120,41 @@ static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *fronte * so for that case pool_where_to_send() should not be called. * */ -static bool process_pg_terminate_backend_func(POOL_QUERY_CONTEXT *query_context) +static bool +process_pg_terminate_backend_func(POOL_QUERY_CONTEXT * query_context) { /* - * locate pg_terminate_backend and get the pid argument, if pg_terminate_backend - * is present in the query + * locate pg_terminate_backend and get the pid argument, if + * pg_terminate_backend is present in the query */ - int backend_pid = pool_get_terminate_backend_pid(query_context->parse_tree); + int backend_pid = pool_get_terminate_backend_pid(query_context->parse_tree); + if (backend_pid > 0) { - int backend_node = 0; - ConnectionInfo* conn = pool_coninfo_backend_pid(backend_pid, &backend_node); - if(conn == NULL) + int backend_node = 0; + ConnectionInfo *conn = pool_coninfo_backend_pid(backend_pid, &backend_node); + + if (conn == NULL) { ereport(LOG, - (errmsg("found the pg_terminate_backend request for backend pid:%d, but the backend connection does not belong to pgpool-II",backend_pid))); - /* we are not able to find the backend connection with the pid - * so there is not much left for us to do here + (errmsg("found the pg_terminate_backend request for backend pid:%d, but the backend connection does not belong to pgpool-II", backend_pid))); + + /* + * we are not able to find the backend connection with the pid so + * there is not much left for us to do here */ return false; } ereport(LOG, - (errmsg("found the pg_terminate_backend request for backend pid:%d on backend node:%d",backend_pid,backend_node), + (errmsg("found the pg_terminate_backend request for backend pid:%d on backend node:%d", backend_pid, backend_node), errdetail("setting the connection flag"))); pool_set_connection_will_be_terminated(conn); - /* It was the pg_terminate_backend call so send the query to appropriate backend */ + + /* + * It was the pg_terminate_backend call so send the query to + * appropriate backend + */ query_context->pg_terminate_backend_conn = conn; pool_force_query_node_to_backend(query_context, backend_node); return true; @@ -157,27 +166,28 @@ static bool process_pg_terminate_backend_func(POOL_QUERY_CONTEXT *query_context) * Process Query('Q') message * Query messages include an SQL string. */ -POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, int len, char *contents) +POOL_STATUS +SimpleQuery(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int len, char *contents) { static char *sq_config = "pool_status"; static char *sq_pools = "pool_pools"; static char *sq_processes = "pool_processes"; - static char *sq_nodes = "pool_nodes"; - static char *sq_version = "pool_version"; - static char *sq_cache = "pool_cache"; - int commit; - List *parse_tree_list; - Node *node = NULL; + static char *sq_nodes = "pool_nodes"; + static char *sq_version = "pool_version"; + static char *sq_cache = "pool_cache"; + int commit; + List *parse_tree_list; + Node *node = NULL; POOL_STATUS status; - int lock_kind; - bool is_likely_select = false; - int specific_error = 0; + int lock_kind; + bool is_likely_select = false; + int specific_error = 0; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; - bool error; + bool error; /* Get session context */ session_context = pool_get_session_context(false); @@ -190,7 +200,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, /* log query to log file if necessary */ if (pool_config->log_statement) - ereport(pool_config->log_statement? LOG: DEBUG1,(errmsg("statement: %s", contents))); + ereport(pool_config->log_statement ? LOG : DEBUG1, (errmsg("statement: %s", contents))); /* * Fetch memory cache if possible @@ -198,25 +208,27 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, is_likely_select = pool_is_likely_select(contents); /* - * If memory query cache enabled and the query seems to be a - * SELECT use query cache if possible. However if we are in an - * explicit transaction and we had writing query before, we should - * not use query cache. This means that even the writing query is - * not anything related to the table which is used the SELECT, we - * do not use cache. Of course we could analyze the SELECT to see - * if it uses the table modified in the transaction, but it will - * need parsing query and accessing to system catalog, which will - * add significant overhead. Moreover if we are in aborted - * transaction, commands should be ignored, so we should not use + * If memory query cache enabled and the query seems to be a SELECT use + * query cache if possible. However if we are in an explicit transaction + * and we had writing query before, we should not use query cache. This + * means that even the writing query is not anything related to the table + * which is used the SELECT, we do not use cache. Of course we could + * analyze the SELECT to see if it uses the table modified in the + * transaction, but it will need parsing query and accessing to system + * catalog, which will add significant overhead. Moreover if we are in + * aborted transaction, commands should be ignored, so we should not use * query cache. */ if (pool_config->memory_cache_enabled && is_likely_select && !pool_is_writing_transaction() && TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) != 'E') { - bool foundp; + bool foundp; - /* If the query is SELECT from table to cache, try to fetch cached result. */ + /* + * If the query is SELECT from table to cache, try to fetch cached + * result. + */ status = pool_fetch_from_memory_cache(frontend, backend, contents, &foundp); if (status != POOL_CONTINUE) @@ -244,9 +256,8 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (*contents == '\0' || *contents == ';' || error == false) { /* - * JBoss sends empty queries for checking connections. - * We replace the empty query with SELECT command not - * to affect load balance. + * JBoss sends empty queries for checking connections. We replace + * the empty query with SELECT command not to affect load balance. * [Pgpool-general] Confused about JDBC and load balancing */ parse_tree_list = raw_parser(POOL_DUMMY_READ_QUERY, &error); @@ -254,18 +265,18 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, else { /* - * Unable to parse the query. Probably syntax error or the - * query is too new and our parser cannot understand. Treat as - * if it were an DELETE command. Note that the DELETE command - * does not execute, instead the original query will be sent - * to backends, which may or may not cause an actual syntax errors. - * The command will be sent to all backends in replication mode - * or master/primary in master/slave mode. + * Unable to parse the query. Probably syntax error or the query + * is too new and our parser cannot understand. Treat as if it + * were an DELETE command. Note that the DELETE command does not + * execute, instead the original query will be sent to backends, + * which may or may not cause an actual syntax errors. The command + * will be sent to all backends in replication mode or + * master/primary in master/slave mode. */ if (!strcmp(remote_host, "[local]")) { ereport(LOG, - (errmsg("Unable to parse the query: \"%s\" from local client", contents))); + (errmsg("Unable to parse the query: \"%s\" from local client", contents))); } else { @@ -288,12 +299,14 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, pool_start_query(query_context, contents, len, node); /* - * If the query is DROP DATABASE, after executing it, cache files directory must be discarded. - * So we have to get the DB's oid before it will be DROPped. + * If the query is DROP DATABASE, after executing it, cache files + * directory must be discarded. So we have to get the DB's oid before + * it will be DROPped. */ if (pool_config->memory_cache_enabled && is_drop_database(node)) { - DropdbStmt *stmt = (DropdbStmt *)node; + DropdbStmt *stmt = (DropdbStmt *) node; + query_context->dboid = pool_get_database_oid_from_dbname(stmt->dbname); if (query_context->dboid != 0) { @@ -314,14 +327,14 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, query_context->is_multi_statement = false; } - /* check COPY FROM STDIN - * if true, set copy_* variable + /* + * check COPY FROM STDIN if true, set copy_* variable */ check_copy_from_stdin(node); if (IsA(node, PgpoolVariableShowStmt)) { - VariableShowStmt *vnode = (VariableShowStmt *)node; + VariableShowStmt *vnode = (VariableShowStmt *) node; report_config_variable(frontend, backend, vnode->name); @@ -333,8 +346,9 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (IsA(node, PgpoolVariableSetStmt)) { - VariableSetStmt *vnode = (VariableSetStmt *)node; + VariableSetStmt *vnode = (VariableSetStmt *) node; const char *value = NULL; + if (vnode->kind == VAR_SET_VALUE) { value = flatten_set_variable_args("name", vnode->args); @@ -357,58 +371,58 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, /* status reporting? */ if (IsA(node, VariableShowStmt)) { - bool is_valid_show_command = false; - VariableShowStmt *vnode = (VariableShowStmt *)node; + bool is_valid_show_command = false; + VariableShowStmt *vnode = (VariableShowStmt *) node; if (!strcmp(sq_config, vnode->name)) - { + { is_valid_show_command = true; ereport(DEBUG1, - (errmsg("SimpleQuery"), + (errmsg("SimpleQuery"), errdetail("config reporting"))); - config_reporting(frontend, backend); - } + config_reporting(frontend, backend); + } else if (!strcmp(sq_pools, vnode->name)) - { + { is_valid_show_command = true; ereport(DEBUG1, - (errmsg("SimpleQuery"), + (errmsg("SimpleQuery"), errdetail("pools reporting"))); - pools_reporting(frontend, backend); - } + pools_reporting(frontend, backend); + } else if (!strcmp(sq_processes, vnode->name)) - { + { is_valid_show_command = true; ereport(DEBUG1, - (errmsg("SimpleQuery"), + (errmsg("SimpleQuery"), errdetail("processes reporting"))); - processes_reporting(frontend, backend); - } + processes_reporting(frontend, backend); + } else if (!strcmp(sq_nodes, vnode->name)) - { + { is_valid_show_command = true; ereport(DEBUG1, - (errmsg("SimpleQuery"), + (errmsg("SimpleQuery"), errdetail("nodes reporting"))); - nodes_reporting(frontend, backend); - } + nodes_reporting(frontend, backend); + } else if (!strcmp(sq_version, vnode->name)) - { + { is_valid_show_command = true; ereport(DEBUG1, - (errmsg("SimpleQuery"), + (errmsg("SimpleQuery"), errdetail("version reporting"))); - version_reporting(frontend, backend); - } + version_reporting(frontend, backend); + } else if (!strcmp(sq_cache, vnode->name)) - { + { is_valid_show_command = true; ereport(DEBUG1, - (errmsg("SimpleQuery"), + (errmsg("SimpleQuery"), errdetail("cache reporting"))); - cache_reporting(frontend, backend); - } + cache_reporting(frontend, backend); + } if (is_valid_show_command) { @@ -420,14 +434,15 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, } /* - * If the table is to be cached, set is_cache_safe TRUE and register table oids. + * If the table is to be cached, set is_cache_safe TRUE and register + * table oids. */ if (pool_config->memory_cache_enabled && query_context->is_multi_statement == false) { - bool is_select_query = false; - int num_oids; - int *oids; - int i; + bool is_select_query = false; + int num_oids; + int *oids; + int i; /* Check if the query is actually SELECT */ if (is_likely_select && IsA(node, SelectStmt)) @@ -447,7 +462,10 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, pool_unset_cache_safe(); } - /* If table is to be cached and the query is DML, save the table oid */ + /* + * If table is to be cached and the query is DML, save the table + * oid + */ if (!is_select_query && !query_context->is_parse_error) { num_oids = pool_extract_table_oids(node, &oids); @@ -455,7 +473,7 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (num_oids > 0) { /* Save to oid buffer */ - for (i=0;i<num_oids;i++) + for (i = 0; i < num_oids; i++) { pool_add_dml_table_oid(oids[i]); } @@ -464,9 +482,9 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, } /* - * pg_terminate function needs special handling, process it if the query - * contains one, otherwise use pool_where_to_send() to decide destination - * backend node for the query + * pg_terminate function needs special handling, process it if the + * query contains one, otherwise use pool_where_to_send() to decide + * destination backend node for the query */ if (process_pg_terminate_backend_func(query_context) == false) { @@ -476,23 +494,27 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, pool_where_to_send(query_context, query_context->original_query, query_context->parse_tree); } + /* * if this is DROP DATABASE command, send USR1 signal to parent and - * ask it to close all idle connections. - * XXX This is overkill. It would be better to close the idle - * connection for the database which DROP DATABASE command tries - * to drop. This is impossible at this point, since we have no way - * to pass such info to other processes. + * ask it to close all idle connections. XXX This is overkill. It + * would be better to close the idle connection for the database which + * DROP DATABASE command tries to drop. This is impossible at this + * point, since we have no way to pass such info to other processes. */ if (is_drop_database(node)) { - int stime = 5; /* XXX give arbitrary time to allow closing idle connections */ + int stime = 5; /* XXX give arbitrary time to allow + * closing idle connections */ ereport(DEBUG1, (errmsg("Query: sending SIGUSR1 signal to parent"))); register_node_operation_request(CLOSE_IDLE_REQUEST, NULL, 0, 0); - /* we need to loop over here since we will get USR1 signal while sleeping */ + /* + * we need to loop over here since we will get USR1 signal while + * sleeping + */ while (stime > 0) { stime = sleep(stime); @@ -512,20 +534,20 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (!RAW_MODE && !SL_MODE) { /* - * If there's only one node to send the command, there's no - * point to start a transaction. + * If there's only one node to send the command, there's no point + * to start a transaction. */ if (pool_multi_node_to_be_sent(query_context)) { /* start a transaction if needed */ - start_internal_transaction(frontend, backend, (Node *)node); + start_internal_transaction(frontend, backend, (Node *) node); /* check if need lock */ lock_kind = need_insert_lock(backend, contents, node); if (lock_kind) { /* if so, issue lock command */ - status = insert_lock(frontend, backend, contents, (InsertStmt *)node, lock_kind); + status = insert_lock(frontend, backend, contents, (InsertStmt *) node, lock_kind); if (status != POOL_CONTINUE) { pool_query_context_destroy(query_context); @@ -543,11 +565,11 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (MAJOR(backend) == PROTO_MAJOR_V2 && is_start_transaction_query(node)) { - int i; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { - if(VALID_BACKEND(i)) + if (VALID_BACKEND(i)) TSTATE(backend, i) = 'T'; } } @@ -559,9 +581,9 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (IsA(node, PrepareStmt)) { msg = pool_create_sent_message('Q', len, contents, 0, - ((PrepareStmt *)node)->name, + ((PrepareStmt *) node)->name, query_context); - session_context->uncompleted_message = msg; + session_context->uncompleted_message = msg; } } @@ -576,10 +598,10 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, */ if (!commit) { - char *rewrite_query; + char *rewrite_query; if (node) - { + { POOL_SENT_MESSAGE *msg = NULL; if (IsA(node, PrepareStmt)) @@ -588,20 +610,20 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, } else if (IsA(node, ExecuteStmt)) { - msg = pool_get_sent_message('Q', ((ExecuteStmt *)node)->name, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('Q', ((ExecuteStmt *) node)->name, POOL_SENT_MESSAGE_CREATED); if (!msg) - msg = pool_get_sent_message('P', ((ExecuteStmt *)node)->name, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('P', ((ExecuteStmt *) node)->name, POOL_SENT_MESSAGE_CREATED); } /* rewrite `now()' to timestamp literal */ rewrite_query = rewrite_timestamp(backend, query_context->parse_tree, false, msg); /* - * If the query is BEGIN READ WRITE or - * BEGIN ... SERIALIZABLE in master/slave mode, - * we send BEGIN to slaves/standbys instead. - * original_query which is BEGIN READ WRITE is sent to primary. - * rewritten_query which is BEGIN is sent to standbys. + * If the query is BEGIN READ WRITE or BEGIN ... SERIALIZABLE + * in master/slave mode, we send BEGIN to slaves/standbys + * instead. original_query which is BEGIN READ WRITE is sent + * to primary. rewritten_query which is BEGIN is sent to + * standbys. */ if (pool_need_to_treat_as_if_default_transaction(query_context)) { @@ -616,9 +638,9 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, } /* - * Optimization effort: If there's only one session, we do - * not need to wait for the master node's response, and - * could execute the query concurrently. + * Optimization effort: If there's only one session, we do not + * need to wait for the master node's response, and could execute + * the query concurrently. */ if (pool_config->num_init_children == 1) { @@ -642,8 +664,8 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, if (specific_error) { - char msg[1024] = POOL_ERROR_QUERY; /* large enough */ - int len = strlen(msg); + char msg[1024] = POOL_ERROR_QUERY; /* large enough */ + int len = strlen(msg); memset(msg + len, 0, sizeof(int)); @@ -660,7 +682,10 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, pool_send_and_wait(query_context, -1, MASTER_NODE_ID); } - /* Send "COMMIT" or "ROLLBACK" to only master node if query is "COMMIT" or "ROLLBACK" */ + /* + * Send "COMMIT" or "ROLLBACK" to only master node if query is + * "COMMIT" or "ROLLBACK" + */ if (commit) pool_send_and_wait(query_context, 1, MASTER_NODE_ID); } @@ -675,52 +700,53 @@ POOL_STATUS SimpleQuery(POOL_CONNECTION *frontend, /* * process EXECUTE (V3 only) */ -POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +Execute(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + int len, char *contents) { - int commit = 0; - char *query = NULL; - Node *node; - int specific_error = 0; + int commit = 0; + char *query = NULL; + Node *node; + int specific_error = 0; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; POOL_SENT_MESSAGE *bind_msg; - bool foundp = false; + bool foundp = false; /* Get session context */ session_context = pool_get_session_context(false); if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Execute message from frontend."), - errdetail("portal: \"%s\"",contents))); + (errmsg("Execute message from frontend."), + errdetail("portal: \"%s\"", contents))); ereport(DEBUG2, - (errmsg("Execute: portal name <%s>", contents))); + (errmsg("Execute: portal name <%s>", contents))); bind_msg = pool_get_sent_message('B', contents, POOL_SENT_MESSAGE_CREATED); if (!bind_msg) - ereport(FATAL, - (return_code(2), - errmsg("unable to Execute"), - errdetail("unable to get bind message"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to Execute"), + errdetail("unable to get bind message"))); - if(!bind_msg->query_context) - ereport(FATAL, - (return_code(2), - errmsg("unable to Execute"), - errdetail("unable to get query context"))); + if (!bind_msg->query_context) + ereport(FATAL, + (return_code(2), + errmsg("unable to Execute"), + errdetail("unable to get query context"))); if (!bind_msg->query_context->original_query) - ereport(FATAL, - (return_code(2), - errmsg("unable to Execute"), - errdetail("unable to get original query"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to Execute"), + errdetail("unable to get original query"))); if (!bind_msg->query_context->parse_tree) - ereport(FATAL, - (return_code(2), - errmsg("unable to Execute"), - errdetail("unable to get parse tree"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to Execute"), + errdetail("unable to get parse tree"))); query_context = bind_msg->query_context; node = bind_msg->query_context->parse_tree; @@ -728,11 +754,11 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, strlcpy(query_string_buffer, query, sizeof(query_string_buffer)); - ereport(DEBUG2,(errmsg("Execute: query string = <%s>", query))); + ereport(DEBUG2, (errmsg("Execute: query string = <%s>", query))); - ereport(DEBUG1,(errmsg("Execute: pool_is_likely_select: %d pool_is_writing_transaction: %d TSTATE: %c", - pool_is_likely_select(query), pool_is_writing_transaction(), - TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID)))); + ereport(DEBUG1, (errmsg("Execute: pool_is_likely_select: %d pool_is_writing_transaction: %d TSTATE: %c", + pool_is_likely_select(query), pool_is_writing_transaction(), + TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID)))); /* * Fetch memory cache if possible @@ -742,15 +768,15 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) != 'E')) { POOL_STATUS status; - char *search_query = NULL; - int len; + char *search_query = NULL; + int len; #define STR_ALLOC_SIZE 1024 - len = strlen(query)+1; - search_query = MemoryContextStrdup(query_context->memory_context,query); + len = strlen(query) + 1; + search_query = MemoryContextStrdup(query_context->memory_context, query); - ereport(DEBUG1,(errmsg("Execute: checkig cache fetch condition"))); + ereport(DEBUG1, (errmsg("Execute: checkig cache fetch condition"))); /* * Add bind message's info to query to search. @@ -758,22 +784,22 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (query_context->is_cache_safe && bind_msg->param_offset && bind_msg->contents) { /* Extract binary contents from bind message */ - char *query_in_bind_msg = bind_msg->contents + bind_msg->param_offset; - char hex_str[4]; /* 02X chars + white space + null end */ - int i; - int alloc_len; + char *query_in_bind_msg = bind_msg->contents + bind_msg->param_offset; + char hex_str[4]; /* 02X chars + white space + null end */ + int i; + int alloc_len; - alloc_len = (len/STR_ALLOC_SIZE+1)*STR_ALLOC_SIZE; + alloc_len = (len / STR_ALLOC_SIZE + 1) * STR_ALLOC_SIZE; search_query = repalloc(search_query, alloc_len); for (i = 0; i < bind_msg->len - bind_msg->param_offset; i++) { - int hexlen; + int hexlen; snprintf(hex_str, sizeof(hex_str), (i == 0) ? " %02X" : "%02X", 0xff & query_in_bind_msg[i]); hexlen = strlen(hex_str); - if ((len+hexlen) >= alloc_len) + if ((len + hexlen) >= alloc_len) { alloc_len += STR_ALLOC_SIZE; search_query = repalloc(search_query, alloc_len); @@ -785,26 +811,29 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, query_context->query_w_hex = search_query; /* - * When a transaction is committed, query_context->temp_cache->query is used - * to create md5 hash to search for query cache. - * So overwrite the query text in temp cache to the one with the hex of bind message. - * If not, md5 hash will be created by the query text without bind message, and - * it will happen to find cache never or to get a wrong result. + * When a transaction is committed, + * query_context->temp_cache->query is used to create md5 hash to + * search for query cache. So overwrite the query text in temp + * cache to the one with the hex of bind message. If not, md5 hash + * will be created by the query text without bind message, and it + * will happen to find cache never or to get a wrong result. * * However, It is possible that temp_cache does not exist. - * Consider following scenario: - * - In the previous execute cache is overflowed, and - * temp_cache discarded. - * - In the subsequent bind/execute uses the same portal + * Consider following scenario: - In the previous execute cache is + * overflowed, and temp_cache discarded. - In the subsequent + * bind/execute uses the same portal */ if (query_context->temp_cache) { pfree(query_context->temp_cache->query); - query_context->temp_cache->query = MemoryContextStrdup(session_context->memory_context,search_query); + query_context->temp_cache->query = MemoryContextStrdup(session_context->memory_context, search_query); } } - /* If the query is SELECT from table to cache, try to fetch cached result. */ + /* + * If the query is SELECT from table to cache, try to fetch cached + * result. + */ status = pool_fetch_from_memory_cache(frontend, backend, search_query, &foundp); if (status != POOL_CONTINUE) @@ -835,11 +864,11 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, } session_context->query_context = query_context; + /* * Calling pool_where_to_send here is dangerous because the node - * parse/bind has been sent could be change by - * pool_where_to_send() and it leads to "portal not found" - * etc. errors. + * parse/bind has been sent could be change by pool_where_to_send() and it + * leads to "portal not found" etc. errors. */ /* check if query is "COMMIT" or "ROLLBACK" */ @@ -866,8 +895,8 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (specific_error) { - char msg[1024] = "pgpool_error_portal"; /* large enough */ - int len = strlen(msg); + char msg[1024] = "pgpool_error_portal"; /* large enough */ + int len = strlen(msg); memset(msg + len, 0, sizeof(int)); @@ -879,13 +908,16 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, pool_extended_send_and_wait(query_context, "E", len, contents, -1, MASTER_NODE_ID, false); } - /* send "COMMIT" or "ROLLBACK" to only master node if query is "COMMIT" or "ROLLBACK" */ + /* + * send "COMMIT" or "ROLLBACK" to only master node if query is + * "COMMIT" or "ROLLBACK" + */ if (commit) { pool_extended_send_and_wait(query_context, "E", len, contents, 1, MASTER_NODE_ID, false); } } - else /* streaming replication mode */ + else /* streaming replication mode */ { POOL_PENDING_MESSAGE *pmsg; @@ -914,16 +946,18 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, ereport(DEBUG1, (errmsg("Execute: TSTATE:%c", TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID)))); + /* - * If the query was not READ SELECT, and we are in an - * explicit transaction, remember that we had a write - * query in this transaction. + * If the query was not READ SELECT, and we are in an explicit + * transaction, remember that we had a write query in this + * transaction. */ if (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) == 'T' || pool_config->disable_load_balance_on_write == DLBOW_ALWAYS) { - /* However, if the query is "SET TRANSACTION READ ONLY" or its variant, - * don't set it. + /* + * However, if the query is "SET TRANSACTION READ ONLY" or its + * variant, don't set it. */ if (!pool_is_transaction_read_only(node)) { @@ -940,21 +974,22 @@ POOL_STATUS Execute(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, /* * process Parse (V3 only) */ -POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +Parse(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + int len, char *contents) { - int deadlock_detected = 0; - int insert_stmt_with_lock = 0; - char *name; - char *stmt; - List *parse_tree_list; - Node *node = NULL; + int deadlock_detected = 0; + int insert_stmt_with_lock = 0; + char *name; + char *stmt; + List *parse_tree_list; + Node *node = NULL; POOL_SENT_MESSAGE *msg; POOL_STATUS status; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; - bool error; + bool error; /* Get session context */ session_context = pool_get_session_context(false); @@ -970,11 +1005,12 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Parse message from frontend."), - errdetail("statement: \"%s\", query: \"%s\"",name, stmt))); + (errmsg("Parse message from frontend."), + errdetail("statement: \"%s\", query: \"%s\"", name, stmt))); /* parse SQL string */ MemoryContext old_context = MemoryContextSwitchTo(query_context->memory_context); + parse_tree_list = raw_parser(stmt, &error); if (parse_tree_list == NIL) @@ -983,9 +1019,8 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (*stmt == '\0' || *stmt == ';' || error == false) { /* - * JBoss sends empty queries for checking connections. - * We replace the empty query with SELECT command not - * to affect load balance. + * JBoss sends empty queries for checking connections. We replace + * the empty query with SELECT command not to affect load balance. * [Pgpool-general] Confused about JDBC and load balancing */ parse_tree_list = raw_parser(POOL_DUMMY_READ_QUERY, &error); @@ -993,13 +1028,13 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, else { /* - * Unable to parse the query. Probably syntax error or the - * query is too new and our parser cannot understand. Treat as - * if it were an DELETE command. Note that the DELETE command - * does not execute, instead the original query will be sent - * to backends, which may or may not cause an actual syntax errors. - * The command will be sent to all backends in replication mode - * or master/primary in master/slave mode. + * Unable to parse the query. Probably syntax error or the query + * is too new and our parser cannot understand. Treat as if it + * were an DELETE command. Note that the DELETE command does not + * execute, instead the original query will be sent to backends, + * which may or may not cause an actual syntax errors. The command + * will be sent to all backends in replication mode or + * master/primary in master/slave mode. */ if (!strcmp(remote_host, "[local]")) { @@ -1024,7 +1059,8 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, node = raw_parser2(parse_tree_list); - /* If replication mode, check to see what kind of insert lock is + /* + * If replication mode, check to see what kind of insert lock is * neccessary. */ if (REPLICATION) @@ -1040,15 +1076,16 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, session_context->uncompleted_message = msg; /* - * If the table is to be cached, set is_cache_safe TRUE and register table oids. + * If the table is to be cached, set is_cache_safe TRUE and register + * table oids. */ if (pool_config->memory_cache_enabled) { - bool is_likely_select = false; - bool is_select_query = false; - int num_oids; - int *oids; - int i; + bool is_likely_select = false; + bool is_select_query = false; + int num_oids; + int *oids; + int i; /* Check if the query is actually SELECT */ is_likely_select = pool_is_likely_select(query_context->original_query); @@ -1069,7 +1106,10 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, pool_unset_cache_safe(); } - /* If table is to be cached and the query is DML, save the table oid */ + /* + * If table is to be cached and the query is DML, save the table + * oid + */ if (!is_select_query && !query_context->is_parse_error) { num_oids = pool_extract_table_oids(node, &oids); @@ -1077,7 +1117,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (num_oids > 0) { /* Save to oid buffer */ - for (i=0;i<num_oids;i++) + for (i = 0; i < num_oids; i++) { pool_add_dml_table_oid(oids[i]); } @@ -1093,14 +1133,13 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (REPLICATION) { - char *rewrite_query; - bool rewrite_to_params = true; + char *rewrite_query; + bool rewrite_to_params = true; /* - * rewrite `now()'. - * if stmt is unnamed, we rewrite `now()' to timestamp constant. - * else we rewrite `now()' to params and expand that at Bind - * message. + * rewrite `now()'. if stmt is unnamed, we rewrite `now()' to + * timestamp constant. else we rewrite `now()' to params and + * expand that at Bind message. */ if (*name == '\0') rewrite_to_params = false; @@ -1108,10 +1147,12 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, rewrite_query = rewrite_timestamp(backend, node, rewrite_to_params, msg); if (rewrite_query != NULL) { - int alloc_len = len - strlen(stmt) + strlen(rewrite_query); - /* switch memory context */ + int alloc_len = len - strlen(stmt) + strlen(rewrite_query); + + /* switch memory context */ MemoryContext oldcxt = MemoryContextSwitchTo(session_context->memory_context); - contents = repalloc(msg->contents,alloc_len); + + contents = repalloc(msg->contents, alloc_len); MemoryContextSwitchTo(oldcxt); strcpy(contents, name); @@ -1134,13 +1175,13 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, } /* - * If the query is BEGIN READ WRITE in master/slave mode, - * we send BEGIN instead of it to slaves/standbys. - * original_query which is BEGIN READ WRITE is sent to primary. - * rewritten_query which is BEGIN is sent to standbys. + * If the query is BEGIN READ WRITE in master/slave mode, we send + * BEGIN instead of it to slaves/standbys. original_query which is + * BEGIN READ WRITE is sent to primary. rewritten_query which is BEGIN + * is sent to standbys. */ if (is_start_transaction_query(query_context->parse_tree) && - is_read_write((TransactionStmt *)query_context->parse_tree) && + is_read_write((TransactionStmt *) query_context->parse_tree) && MASTER_SLAVE) { query_context->rewritten_query = pstrdup("BEGIN"); @@ -1152,11 +1193,11 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, */ if (REPLICATION) { - char kind; + char kind; if (TSTATE(backend, MASTER_NODE_ID) != 'T') { - int i; + int i; /* synchronize transaction state */ for (i = 0; i < NUM_BACKENDS; i++) @@ -1169,9 +1210,9 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, kind = pool_read_kind(backend); if (kind != 'Z') - ereport(ERROR, - (errmsg("unable to parse the query"), - errdetail("invalid read kind"))); + ereport(ERROR, + (errmsg("unable to parse the query"), + errdetail("invalid read kind"))); /* * SYNC message returns "Ready for Query" message. @@ -1199,11 +1240,11 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (insert_stmt_with_lock) { /* start a transaction if needed and lock the table */ - status = insert_lock(frontend, backend, stmt, (InsertStmt *)query_context->parse_tree, insert_stmt_with_lock); + status = insert_lock(frontend, backend, stmt, (InsertStmt *) query_context->parse_tree, insert_stmt_with_lock); if (status != POOL_CONTINUE) - ereport(ERROR, - (errmsg("unable to parse the query"), - errdetail("unable to get insert lock"))); + ereport(ERROR, + (errmsg("unable to parse the query"), + errdetail("unable to get insert lock"))); } } @@ -1211,28 +1252,27 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (REPLICATION || SLONY) { /* - * We must synchronize because Parse message acquires table - * locks. + * We must synchronize because Parse message acquires table locks. */ ereport(DEBUG1, (errmsg("Parse: waiting for master completing the query"))); - pool_extended_send_and_wait(query_context, "P", len, contents, 1, MASTER_NODE_ID, false); + pool_extended_send_and_wait(query_context, "P", len, contents, 1, MASTER_NODE_ID, false); /* - * We must check deadlock error because a aborted transaction - * by detecting deadlock isn't same on all nodes. - * If a transaction is aborted on master node, pgpool send a - * error query to another nodes. + * We must check deadlock error because a aborted transaction by + * detecting deadlock isn't same on all nodes. If a transaction is + * aborted on master node, pgpool send a error query to another nodes. */ deadlock_detected = detect_deadlock_error(MASTER(backend), MAJOR(backend)); - /* - * Check if other than deadlock error detected. If so, emit - * log. This is useful when invalid encoding error occurs. In - * this case, PostgreSQL does not report what statement caused - * that error and make users confused. - */ - per_node_error_log(backend, MASTER_NODE_ID, stmt, "Parse: Error or notice message from backend: ", true); + + /* + * Check if other than deadlock error detected. If so, emit log. This + * is useful when invalid encoding error occurs. In this case, + * PostgreSQL does not report what statement caused that error and + * make users confused. + */ + per_node_error_log(backend, MASTER_NODE_ID, stmt, "Parse: Error or notice message from backend: ", true); if (deadlock_detected) { @@ -1252,7 +1292,7 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, pool_query_context_destroy(error_qc); - pool_set_query_in_progress(); + pool_set_query_in_progress(); session_context->query_context = query_context; } else @@ -1264,7 +1304,10 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, { POOL_PENDING_MESSAGE *pmsg; - /* XXX fix me:even with streaming replication mode, couldn't we have a deadlock */ + /* + * XXX fix me:even with streaming replication mode, couldn't we have a + * deadlock + */ pool_set_query_in_progress(); #ifdef NOT_USED pool_clear_sync_map(); @@ -1290,21 +1333,23 @@ POOL_STATUS Parse(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, } -POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +Bind(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + int len, char *contents) { - char *pstmt_name; - char *portal_name; - char *rewrite_msg = NULL; + char *pstmt_name; + char *portal_name; + char *rewrite_msg = NULL; POOL_SENT_MESSAGE *parse_msg; POOL_SENT_MESSAGE *bind_msg; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; - int insert_stmt_with_lock = 0; - bool nowait; + int insert_stmt_with_lock = 0; + bool nowait; /* Get session context */ session_context = pool_get_session_context(false); + /* * Rewrite message */ @@ -1313,16 +1358,16 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Bind message from frontend."), - errdetail("portal: \"%s\", statement: \"%s\"",portal_name, pstmt_name))); + (errmsg("Bind message from frontend."), + errdetail("portal: \"%s\", statement: \"%s\"", portal_name, pstmt_name))); parse_msg = pool_get_sent_message('Q', pstmt_name, POOL_SENT_MESSAGE_CREATED); if (!parse_msg) parse_msg = pool_get_sent_message('P', pstmt_name, POOL_SENT_MESSAGE_CREATED); if (!parse_msg) { - ereport(FATAL, - (errmsg("unable to bind"), - errdetail("cannot get parse message \"%s\"", pstmt_name))); + ereport(FATAL, + (errmsg("unable to bind"), + errdetail("cannot get parse message \"%s\"", pstmt_name))); } bind_msg = pool_create_sent_message('B', len, contents, @@ -1332,13 +1377,14 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, query_context = parse_msg->query_context; if (!query_context) { - ereport(FATAL, - (errmsg("unable to bind"), - errdetail("cannot get the query context"))); + ereport(FATAL, + (errmsg("unable to bind"), + errdetail("cannot get the query context"))); } /* - * If the query can be cached, save its offset of query text in bind message's content. + * If the query can be cached, save its offset of query text in bind + * message's content. */ if (query_context->is_cache_safe) { @@ -1398,7 +1444,7 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, ereport(DEBUG1, (errmsg("Bind: issuing insert lock"))); /* issue a LOCK command to keep consistency */ - if (insert_lock(frontend, backend, query_context->original_query, (InsertStmt *)query_context->parse_tree, insert_stmt_with_lock) != POOL_CONTINUE) + if (insert_lock(frontend, backend, query_context->original_query, (InsertStmt *) query_context->parse_tree, insert_stmt_with_lock) != POOL_CONTINUE) { pool_query_context_destroy(query_context); return POOL_END; @@ -1407,7 +1453,7 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, } ereport(DEBUG1, - (errmsg("Bind: waiting for master completing the query"))); + (errmsg("Bind: waiting for master completing the query"))); pool_set_query_in_progress(); @@ -1437,19 +1483,20 @@ POOL_STATUS Bind(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, pool_pending_message_free_pending_message(pmsg); } - if(rewrite_msg) + if (rewrite_msg) pfree(rewrite_msg); return POOL_CONTINUE; } -POOL_STATUS Describe(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +Describe(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + int len, char *contents) { POOL_SENT_MESSAGE *msg; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; - bool nowait; + bool nowait; /* Get session context */ session_context = pool_get_session_context(false); @@ -1459,52 +1506,51 @@ POOL_STATUS Describe(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, { if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Describe message from frontend."), - errdetail("statement: \"%s\"",contents+1 ))); - msg = pool_get_sent_message('Q', contents+1, POOL_SENT_MESSAGE_CREATED); + (errmsg("Describe message from frontend."), + errdetail("statement: \"%s\"", contents + 1))); + msg = pool_get_sent_message('Q', contents + 1, POOL_SENT_MESSAGE_CREATED); if (!msg) - msg = pool_get_sent_message('P', contents+1, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('P', contents + 1, POOL_SENT_MESSAGE_CREATED); if (!msg) - ereport(FATAL, - (return_code(2), - errmsg("unable to execute Describe"), - errdetail("unable to get the parse message"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to execute Describe"), + errdetail("unable to get the parse message"))); } /* Portal */ else { if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Describe message from frontend."), - errdetail("portal: \"%s\"",contents+1 ))); - msg = pool_get_sent_message('B', contents+1, POOL_SENT_MESSAGE_CREATED); + (errmsg("Describe message from frontend."), + errdetail("portal: \"%s\"", contents + 1))); + msg = pool_get_sent_message('B', contents + 1, POOL_SENT_MESSAGE_CREATED); if (!msg) - ereport(FATAL, - (return_code(2), - errmsg("unable to execute Describe"), - errdetail("unable to get the bind message"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to execute Describe"), + errdetail("unable to get the bind message"))); } query_context = msg->query_context; if (query_context == NULL) - ereport(FATAL, - (return_code(2), - errmsg("unable to execute Describe"), - errdetail("unable to get the query context"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to execute Describe"), + errdetail("unable to get the query context"))); session_context->query_context = query_context; /* * Calling pool_where_to_send here is dangerous because the node - * parse/bind has been sent could be change by - * pool_where_to_send() and it leads to "portal not found" - * etc. errors. + * parse/bind has been sent could be change by pool_where_to_send() and it + * leads to "portal not found" etc. errors. */ - ereport(DEBUG1, - (errmsg("Describe: waiting for master completing the query"))); + ereport(DEBUG1, + (errmsg("Describe: waiting for master completing the query"))); - nowait = (SL_MODE? true: false); + nowait = (SL_MODE ? true : false); pool_set_query_in_progress(); pool_extended_send_and_wait(query_context, "D", len, contents, 1, MASTER_NODE_ID, nowait); @@ -1528,8 +1574,9 @@ POOL_STATUS Describe(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, } -POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +Close(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + int len, char *contents) { POOL_SENT_MESSAGE *msg; POOL_SESSION_CONTEXT *session_context; @@ -1541,27 +1588,28 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, /* Prepared Statement */ if (*contents == 'S') { - msg = pool_get_sent_message('Q', contents+1, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('Q', contents + 1, POOL_SENT_MESSAGE_CREATED); if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Close message from frontend."), - errdetail("statement: \"%s\"",contents+1))); + (errmsg("Close message from frontend."), + errdetail("statement: \"%s\"", contents + 1))); if (!msg) - msg = pool_get_sent_message('P', contents+1, POOL_SENT_MESSAGE_CREATED); + msg = pool_get_sent_message('P', contents + 1, POOL_SENT_MESSAGE_CREATED); } /* Portal */ else if (*contents == 'P') { if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Close message from frontend."), - errdetail("portal: \"%s\"",contents+1))); - msg = pool_get_sent_message('B', contents+1, POOL_SENT_MESSAGE_CREATED); + (errmsg("Close message from frontend."), + errdetail("portal: \"%s\"", contents + 1))); + msg = pool_get_sent_message('B', contents + 1, POOL_SENT_MESSAGE_CREATED); } else - ereport(FATAL, - (return_code(2), - errmsg("unable to execute close, invalid message"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to execute close, invalid message"))); + /* * As per the postgresql, calling close on non existing portals or * statements is not an error. So on the same footings we will ignore all @@ -1570,7 +1618,8 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, */ if (!msg) { - int len = htonl(4); + int len = htonl(4); + pool_set_command_success(); pool_unset_query_in_progress(); @@ -1584,16 +1633,20 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, query_context = msg->query_context; if (!query_context) - ereport(FATAL, - (return_code(2), - errmsg("unable to execute close"), - errdetail("unable to get the query context"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to execute close"), + errdetail("unable to get the query context"))); session_context->query_context = query_context; - /* pool_where_to_send(query_context, query_context->original_query, query_context->parse_tree); */ - ereport(DEBUG1, - (errmsg("Close: waiting for master completing the query"))); + /* + * pool_where_to_send(query_context, query_context->original_query, + * query_context->parse_tree); + */ + + ereport(DEBUG1, + (errmsg("Close: waiting for master completing the query"))); pool_set_query_in_progress(); @@ -1605,9 +1658,10 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, else { POOL_PENDING_MESSAGE *pmsg; - bool where_to_send_save[MAX_NUM_BACKENDS]; + bool where_to_send_save[MAX_NUM_BACKENDS]; - /* Parse_before_bind() may have sent a bind message to the primary + /* + * Parse_before_bind() may have sent a bind message to the primary * node id. So send the close message to the primary node as well. * Even if not, sending a close message for non existing * statement/portal is harmless. No error will happen. @@ -1646,7 +1700,7 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, * Remove sent message */ ereport(DEBUG1, - (errmsg("Close: removing sent message %c %s", *contents, contents+1))); + (errmsg("Close: removing sent message %c %s", *contents, contents + 1))); pool_set_sent_message_state(msg); } @@ -1654,14 +1708,15 @@ POOL_STATUS Close(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, } -POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - int len, char *contents) +POOL_STATUS +FunctionCall3(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + int len, char *contents) { /* * If Function call message for lo_creat, rewrite it */ - char *rewrite_lo; - int rewrite_len; + char *rewrite_lo; + int rewrite_len; rewrite_lo = pool_rewrite_lo_creat('F', contents, len, frontend, backend, &rewrite_len); @@ -1671,7 +1726,7 @@ POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe contents = rewrite_lo; len = rewrite_len; } - return SimpleForwardToBackend('F', frontend, backend, len, contents); + return SimpleForwardToBackend('F', frontend, backend, len, contents); } /* @@ -1684,17 +1739,18 @@ POOL_STATUS FunctionCall3(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe * to all DB nodes to abort transaction or do failover. * - internal transaction is closed */ -POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, bool send_ready, bool cache_commit) +POOL_STATUS +ReadyForQuery(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, bool send_ready, bool cache_commit) { - int i; - int len; + int i; + int len; signed char kind; signed char state = 0; POOL_SESSION_CONTEXT *session_context; - Node *node = NULL; - char *query = NULL; - bool got_estate = false; + Node *node = NULL; + char *query = NULL; + bool got_estate = false; /* * It is possible that the "ignore until sync is received" flag was set if @@ -1712,67 +1768,65 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, /* * If the numbers of update tuples are differ and - * failover_if_affected_tuples_mismatch is false, we abort - * transactions by using do_error_command. If - * failover_if_affected_tuples_mismatch is true, trigger failover. - * This only works with PROTO_MAJOR_V3. + * failover_if_affected_tuples_mismatch is false, we abort transactions by + * using do_error_command. If failover_if_affected_tuples_mismatch is + * true, trigger failover. This only works with PROTO_MAJOR_V3. */ if (session_context->mismatch_ntuples && MAJOR(backend) == PROTO_MAJOR_V3) { - int i; - char kind; + int i; + char kind; /* - * If failover_if_affected_tuples_mismatch, is true, then - * decide victim nodes by using find_victim_nodes and - * degenerate them. + * If failover_if_affected_tuples_mismatch, is true, then decide + * victim nodes by using find_victim_nodes and degenerate them. */ if (pool_config->failover_if_affected_tuples_mismatch) { - int *victim_nodes; - int number_of_nodes; - char msgbuf[128]; + int *victim_nodes; + int number_of_nodes; + char msgbuf[128]; victim_nodes = find_victim_nodes(session_context->ntuples, NUM_BACKENDS, MASTER_NODE_ID, &number_of_nodes); if (victim_nodes) { - int i; - String *msg; + int i; + String *msg; msg = init_string("ReadyForQuery: Degenerate backends:"); - for (i=0;i<number_of_nodes;i++) + for (i = 0; i < number_of_nodes; i++) { snprintf(msgbuf, sizeof(msgbuf), " %d", victim_nodes[i]); string_append_char(msg, msgbuf); } ereport(LOG, - (errmsg("processing ready for query message"), + (errmsg("processing ready for query message"), errdetail("%s", msg->data))); free_string(msg); msg = init_string("ReadyForQuery: Number of affected tuples are:"); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { snprintf(msgbuf, sizeof(msgbuf), " %d", session_context->ntuples[i]); string_append_char(msg, msgbuf); } ereport(LOG, - (errmsg("processing ready for query message"), + (errmsg("processing ready for query message"), errdetail("%s", msg->data))); free_string(msg); - degenerate_backend_set(victim_nodes, number_of_nodes, REQ_DETAIL_CONFIRMED|REQ_DETAIL_SWITCHOVER); + degenerate_backend_set(victim_nodes, number_of_nodes, REQ_DETAIL_CONFIRMED | REQ_DETAIL_SWITCHOVER); child_exit(POOL_EXIT_AND_RESTART); } else { ereport(LOG, - (errmsg("processing ready for query message"), + (errmsg("processing ready for query message"), errdetail("find_victim_nodes returned no victim node"))); } } @@ -1798,7 +1852,7 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, } /* loop through until we get ReadyForQuery */ - for(;;) + for (;;) { kind = pool_read_kind(backend); if (kind < 0) @@ -1809,11 +1863,11 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, /* put the message back to read buffer */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { - pool_unread(CONNECTION(backend,i), &kind, 1); + pool_unread(CONNECTION(backend, i), &kind, 1); } } @@ -1825,8 +1879,8 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, } /* - * if a transaction is started for insert lock, we need to close - * the transaction. + * if a transaction is started for insert lock, we need to close the + * transaction. */ /* if (pool_is_query_in_progress() && allow_close_transaction) */ if (allow_close_transaction) @@ -1839,13 +1893,14 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, { if ((len = pool_read_message_length(backend)) < 0) return POOL_END; + /* * Set transaction state for each node */ state = TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -1855,16 +1910,17 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, TSTATE(backend, i) = kind; ereport(DEBUG5, - (errmsg("processing ReadyForQuery"), - errdetail("transaction state '%c'(%02x)", state,state))); + (errmsg("processing ReadyForQuery"), + errdetail("transaction state '%c'(%02x)", state, state))); + /* - * The transaction state to be returned to frontend is - * master's. + * The transaction state to be returned to frontend is master's. */ if (i == (MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID)) { state = kind; } + /* * However, if the state is 'E', then frontend should had been * already reported an ERROR. So, to match with that, let be the @@ -1904,10 +1960,11 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, if (cache_commit && pool_config->memory_cache_enabled) { - /* If we are doing extended query and the state is after EXECUTE, - * then we can commit cache. - * We check latter condition by looking at query_context->query_w_hex. - * This check is necessary for certain frame work such as PHP PDO. + /* + * If we are doing extended query and the state is after + * EXECUTE, then we can commit cache. We check latter + * condition by looking at query_context->query_w_hex. This + * check is necessary for certain frame work such as PHP PDO. * It sends Sync message right after PARSE and it produces * "Ready for query" message from backend. */ @@ -1917,8 +1974,8 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, session_context->query_context->query_state[MASTER_NODE_ID] == POOL_EXECUTE_COMPLETE) { pool_handle_query_cache(backend, session_context->query_context->query_w_hex, node, state); - if(session_context->query_context->query_w_hex) - pfree(session_context->query_context->query_w_hex); + if (session_context->query_context->query_w_hex) + pfree(session_context->query_context->query_w_hex); session_context->query_context->query_w_hex = NULL; } } @@ -1926,23 +1983,25 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, { if (MAJOR(backend) != PROTO_MAJOR_V3) { - state = 'I'; /* XXX I don't think query cache works with PROTO2 protocol */ + state = 'I'; /* XXX I don't think query cache works + * with PROTO2 protocol */ } pool_handle_query_cache(backend, query, node, state); } } } + /* - * If PREPARE or extended query protocol commands caused error, - * remove the temporary saved message. - * (except when ReadyForQuery() is called during Parse() of extended queries) + * If PREPARE or extended query protocol commands caused error, remove + * the temporary saved message. (except when ReadyForQuery() is called + * during Parse() of extended queries) */ else { if ((pool_is_doing_extended_query_message() && session_context->query_context->query_state[MASTER_NODE_ID] != POOL_UNPARSED && - session_context->uncompleted_message) || - (!pool_is_doing_extended_query_message() && session_context->uncompleted_message && + session_context->uncompleted_message) || + (!pool_is_doing_extended_query_message() && session_context->uncompleted_message && session_context->uncompleted_message->kind != 0)) { pool_add_sent_message(session_context->uncompleted_message); @@ -1957,9 +2016,9 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, if (!pool_is_doing_extended_query_message()) { if (!(node && IsA(node, PrepareStmt))) - { + { pool_query_context_destroy(pool_get_session_context(false)->query_context); - } + } } /* @@ -1973,12 +2032,12 @@ POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, /* * Close running transactions on standbys. */ -static POOL_STATUS close_standby_transactions(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +static POOL_STATUS close_standby_transactions(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - int i; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (CONNECTION_SLOT(backend, i) && TSTATE(backend, i) == 'T' && @@ -1989,15 +2048,16 @@ static POOL_STATUS close_standby_transactions(POOL_CONNECTION *frontend, if (do_command(frontend, CONNECTION(backend, i), "COMMIT", MAJOR(backend), MASTER_CONNECTION(backend)->pid, MASTER_CONNECTION(backend)->key, 0) != POOL_CONTINUE) - ereport(ERROR, - (errmsg("unable to close standby transactions"), - errdetail("do_command returned DEADLOCK status"))); + ereport(ERROR, + (errmsg("unable to close standby transactions"), + errdetail("do_command returned DEADLOCK status"))); } } return POOL_CONTINUE; } -POOL_STATUS ParseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +POOL_STATUS +ParseComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { POOL_SESSION_CONTEXT *session_context; @@ -2020,7 +2080,8 @@ POOL_STATUS ParseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe return SimpleForwardToFrontend('1', frontend, backend); } -POOL_STATUS BindComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +POOL_STATUS +BindComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { POOL_SESSION_CONTEXT *session_context; @@ -2043,12 +2104,13 @@ POOL_STATUS BindComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen return SimpleForwardToFrontend('2', frontend, backend); } -POOL_STATUS CloseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +POOL_STATUS +CloseComplete(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { POOL_SESSION_CONTEXT *session_context; POOL_STATUS status; - char kind = ' '; - char *name = ""; + char kind = ' '; + char *name = ""; /* Get session context */ session_context = pool_get_session_context(false); @@ -2075,7 +2137,7 @@ POOL_STATUS CloseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe { kind = pool_get_close_message_spec(pmsg); name = pool_get_close_message_name(pmsg); - kind = kind=='S'?'P':'B'; + kind = kind == 'S' ? 'P' : 'B'; } pool_pending_message_free_pending_message(pmsg); } @@ -2110,18 +2172,22 @@ POOL_STATUS CloseComplete(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe return status; } -POOL_STATUS ParameterDescription(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +ParameterDescription(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - int len, len1 = 0; - char *p = NULL; - char *p1 = NULL; - int sendlen; - int i; + int len, + len1 = 0; + char *p = NULL; + char *p1 = NULL; + int sendlen; + int i; POOL_SESSION_CONTEXT *session_context; - int num_params, send_num_params, num_dmy; - char kind = 't'; + int num_params, + send_num_params, + num_dmy; + char kind = 't'; session_context = pool_get_session_context(false); @@ -2144,15 +2210,15 @@ POOL_STATUS ParameterDescription(POOL_CONNECTION *frontend, p = pool_read2(MASTER(backend), len); if (p == NULL) - ereport(ERROR, + ereport(ERROR, (errmsg("ParameterDescription. connection error"), - errdetail("read from backend failed"))); + errdetail("read from backend failed"))); p1 = palloc(len); memcpy(p1, p, len); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i) && !IS_MASTER_NODE_ID(i)) { @@ -2165,12 +2231,12 @@ POOL_STATUS ParameterDescription(POOL_CONNECTION *frontend, if (p == NULL) ereport(ERROR, (errmsg("ParameterDescription. connection error"), - errdetail("read from backend no %d failed",i))); + errdetail("read from backend no %d failed", i))); if (len != len1) ereport(DEBUG1, (errmsg("ParameterDescription. backends does not match"), - errdetail("length does not match between backends master(%d) %d th backend(%d) kind:(%c)",len, i, len1, kind))); + errdetail("length does not match between backends master(%d) %d th backend(%d) kind:(%c)", len, i, len1, kind))); } } @@ -2190,8 +2256,9 @@ POOL_STATUS ParameterDescription(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +ErrorResponse3(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { POOL_STATUS ret; @@ -2205,15 +2272,16 @@ POOL_STATUS ErrorResponse3(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +FunctionCall(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char dummy[2]; - int oid; - int argn; - int i; + char dummy[2]; + int oid; + int argn; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2224,7 +2292,7 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, /* dummy */ pool_read(frontend, dummy, sizeof(dummy)); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2235,7 +2303,7 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, /* function object id */ pool_read(frontend, &oid, sizeof(oid)); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2246,7 +2314,7 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, /* number of arguments */ pool_read(frontend, &argn, sizeof(argn)); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2256,15 +2324,15 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, argn = ntohl(argn); - for (i=0;i<argn;i++) + for (i = 0; i < argn; i++) { - int len; - char *arg; + int len; + char *arg; /* length of each argument in bytes */ pool_read(frontend, &len, sizeof(len)); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2276,12 +2344,12 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, /* argument value itself */ if ((arg = pool_read2(frontend, len)) == NULL) - ereport(FATAL, - (return_code(2), - errmsg("failed to process function call"), - errdetail("read from frontend failed"))); + ereport(FATAL, + (return_code(2), + errmsg("failed to process function call"), + errdetail("read from frontend failed"))); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2290,7 +2358,7 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, } } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2300,14 +2368,15 @@ POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, return POOL_CONTINUE; } -POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +ProcessFrontendResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { - char fkind; - char *bufp = NULL; - char *contents; + char fkind; + char *bufp = NULL; + char *contents; POOL_STATUS status; - int len = 0; + int len = 0; /* Get session context */ pool_get_session_context(false); @@ -2318,16 +2387,16 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, pool_read(frontend, &fkind, 1); ereport(DEBUG5, - (errmsg("processing frontend response"), - errdetail("received kind '%c'(%02x) from frontend",fkind,fkind))); + (errmsg("processing frontend response"), + errdetail("received kind '%c'(%02x) from frontend", fkind, fkind))); if (MAJOR(backend) == PROTO_MAJOR_V3) { if (pool_read(frontend, &len, sizeof(len)) < 0) - ereport(ERROR, - (errmsg("unable to process frontend response"), - errdetail("failed to read message length from frontend. frontend abnormally exited"))); + ereport(ERROR, + (errmsg("unable to process frontend response"), + errdetail("failed to read message length from frontend. frontend abnormally exited"))); len = ntohl(len) - 4; if (len > 0) @@ -2343,15 +2412,15 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, } if (len > 0 && bufp == NULL) - ereport(ERROR, - (errmsg("unable to process frontend response"), - errdetail("failed to read message from frontend. frontend abnormally exited"))); + ereport(ERROR, + (errmsg("unable to process frontend response"), + errdetail("failed to read message from frontend. frontend abnormally exited"))); if (fkind != 'S' && pool_is_ignore_till_sync()) { /* - * Flag setting for calling ProcessBackendResponse() - * in pool_process_query(). + * Flag setting for calling ProcessBackendResponse() in + * pool_process_query(). */ if (!pool_is_query_in_progress()) pool_set_query_in_progress(); @@ -2362,9 +2431,9 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, pool_unset_doing_extended_query_message(); /* - * Allocate buffer and copy the packet contents. Because inside - * these protocol modules, pool_read2 maybe called and modify its - * buffer contents. + * Allocate buffer and copy the packet contents. Because inside these + * protocol modules, pool_read2 maybe called and modify its buffer + * contents. */ if (len > 0) { @@ -2374,8 +2443,8 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, else { /* - * Set dummy content if len <= 0. - * this happens only when protocol version is 2. + * Set dummy content if len <= 0. this happens only when protocol + * version is 2. */ contents = palloc(1); memcpy(contents, "", 1); @@ -2383,33 +2452,33 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, switch (fkind) { - POOL_QUERY_CONTEXT *query_context; - char *query; - Node *node; - List *parse_tree_list; - bool error; + POOL_QUERY_CONTEXT *query_context; + char *query; + Node *node; + List *parse_tree_list; + bool error; - case 'X': /* Terminate */ - if(contents) + case 'X': /* Terminate */ + if (contents) pfree(contents); if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Terminate message from frontend."))); - ereport(DEBUG5, - (errmsg("Frontend terminated"), - errdetail("received message kind 'X' from frontend"))); - return POOL_END; + (errmsg("Terminate message from frontend."))); + ereport(DEBUG5, + (errmsg("Frontend terminated"), + errdetail("received message kind 'X' from frontend"))); + return POOL_END; - case 'Q': /* Query */ + case 'Q': /* Query */ allow_close_transaction = 1; if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Query message from frontend."), - errdetail("query: \"%s\"",contents))); + (errmsg("Query message from frontend."), + errdetail("query: \"%s\"", contents))); status = SimpleQuery(frontend, backend, len, contents); break; - case 'E': /* Execute */ + case 'E': /* Execute */ allow_close_transaction = 1; pool_set_doing_extended_query_message(); if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) @@ -2417,33 +2486,33 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, status = Execute(frontend, backend, len, contents); break; - case 'P': /* Parse */ + case 'P': /* Parse */ allow_close_transaction = 0; pool_set_doing_extended_query_message(); status = Parse(frontend, backend, len, contents); break; - case 'B': /* Bind */ + case 'B': /* Bind */ pool_set_doing_extended_query_message(); status = Bind(frontend, backend, len, contents); break; - case 'C': /* Close */ + case 'C': /* Close */ pool_set_doing_extended_query_message(); if (!pool_is_query_in_progress() && !pool_is_ignore_till_sync()) pool_set_query_in_progress(); status = Close(frontend, backend, len, contents); break; - case 'D': /* Describe */ + case 'D': /* Describe */ pool_set_doing_extended_query_message(); status = Describe(frontend, backend, len, contents); break; - case 'S': /* Sync */ + case 'S': /* Sync */ if (pool_config->log_client_messages) ereport(LOG, - (errmsg("Sync message from frontend."))); + (errmsg("Sync message from frontend."))); pool_set_doing_extended_query_message(); if (pool_is_ignore_till_sync()) pool_unset_ignore_till_sync(); @@ -2468,15 +2537,17 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, } break; - case 'F': /* FunctionCall */ + case 'F': /* FunctionCall */ if (pool_config->log_client_messages) { - int oid; + int oid; + memcpy(&oid, contents, sizeof(int)); ereport(LOG, - (errmsg("FunctionCall message from frontend."), - errdetail("oid: \"%d\"", ntohl(oid) ))); + (errmsg("FunctionCall message from frontend."), + errdetail("oid: \"%d\"", ntohl(oid)))); } + /* * Create dummy query context as if it were an INSERT. */ @@ -2500,13 +2571,13 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, break; - case 'c': /* CopyDone */ - case 'd': /* CopyData */ - case 'f': /* CopyFail */ - case 'H': /* Flush */ + case 'c': /* CopyDone */ + case 'd': /* CopyData */ + case 'f': /* CopyFail */ + case 'H': /* Flush */ if (fkind == 'H' && pool_config->log_client_messages) ereport(LOG, - (errmsg("Flush message from frontend."))); + (errmsg("Flush message from frontend."))); if (MAJOR(backend) == PROTO_MAJOR_V3) { if (fkind == 'H') @@ -2528,29 +2599,30 @@ POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, } default: - ereport(FATAL, - (return_code(2), - errmsg("unable to process frontend response"), - errdetail("unknown message type %c(%02x)", fkind, fkind))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process frontend response"), + errdetail("unknown message type %c(%02x)", fkind, fkind))); } - if(contents) + if (contents) pfree(contents); if (status != POOL_CONTINUE) - ereport(FATAL, - (return_code(2), - errmsg("unable to process frontend response"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process frontend response"))); return status; } -POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - int *state, short *num_fields) +POOL_STATUS +ProcessBackendResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + int *state, short *num_fields) { - int status = POOL_CONTINUE; - char kind; + int status = POOL_CONTINUE; + char kind; /* Get session context */ pool_get_session_context(false); @@ -2577,56 +2649,60 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, return POOL_CONTINUE; } - read_kind_from_backend(frontend, backend, &kind); + read_kind_from_backend(frontend, backend, &kind); /* * Sanity check */ if (kind == 0) { - ereport(FATAL, - (return_code(2), - errmsg("unable to process backend response"), - errdetail("invalid message kind sent by backend connection"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process backend response"), + errdetail("invalid message kind sent by backend connection"))); } ereport(DEBUG5, - (errmsg("processing backend response"), - errdetail("received kind '%c'(%02x) from backend",kind,kind))); + (errmsg("processing backend response"), + errdetail("received kind '%c'(%02x) from backend", kind, kind))); if (MAJOR(backend) == PROTO_MAJOR_V3) { switch (kind) { - case 'G': /* CopyInResponse */ + case 'G': /* CopyInResponse */ status = CopyInResponse(frontend, backend); break; - case 'S': /* ParameterStatus */ + case 'S': /* ParameterStatus */ status = ParameterStatus(frontend, backend); break; - case 'Z': /* ReadyForQuery */ + case 'Z': /* ReadyForQuery */ ereport(DEBUG5, - (errmsg("processing backend response"), + (errmsg("processing backend response"), errdetail("Ready For Query received"))); status = ReadyForQuery(frontend, backend, true, true); #ifdef DEBUG extern bool stop_now; + if (stop_now) exit(0); #endif break; - case '1': /* ParseComplete */ + case '1': /* ParseComplete */ if (SL_MODE) { POOL_PENDING_MESSAGE *pmsg; + pmsg = pool_pending_message_get_previous_message(); if (pmsg && pmsg->not_forward_to_frontend) { - /* parse_before_bind() was called. Do not foward the - * parse complete message to frontend. */ + /* + * parse_before_bind() was called. Do not foward the + * parse complete message to frontend. + */ ereport(DEBUG5, (errmsg("processing backend response"), errdetail("do not forward parse complete message to frontend"))); @@ -2642,27 +2718,31 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, pool_unset_query_in_progress(); break; - case '2': /* BindComplete */ + case '2': /* BindComplete */ status = BindComplete(frontend, backend); pool_set_command_success(); pool_unset_query_in_progress(); break; - case '3': /* CloseComplete */ + case '3': /* CloseComplete */ if (SL_MODE) { POOL_PENDING_MESSAGE *pmsg; + pmsg = pool_pending_message_get_previous_message(); if (pmsg && pmsg->not_forward_to_frontend) { - /* parse_before_bind() was called. Do not foward the - * close complete message to frontend. */ + /* + * parse_before_bind() was called. Do not foward the + * close complete message to frontend. + */ ereport(DEBUG5, (errmsg("processing backend response"), errdetail("do not forward close complete message to frontend"))); pool_discard_packet_contents(backend); - /* Remove pending message here because + /* + * Remove pending message here because * read_kind_from_backend() did not do it. */ pmsg = pool_pending_message_pull_out(); @@ -2680,7 +2760,7 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, pool_unset_query_in_progress(); break; - case 'E': /* ErrorResponse */ + case 'E': /* ErrorResponse */ status = ErrorResponse3(frontend, backend); pool_unset_command_success(); if (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : @@ -2695,20 +2775,22 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, } break; - case 'C': /* CommandComplete */ + case 'C': /* CommandComplete */ status = CommandComplete(frontend, backend, true); pool_set_command_success(); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; - case 't': /* ParameterDescription */ + case 't': /* ParameterDescription */ status = ParameterDescription(frontend, backend); break; - case 'I': /* EmptyQueryResponse */ + case 'I': /* EmptyQueryResponse */ status = CommandComplete(frontend, backend, false); - /* Empty query response message should be treated same as + + /* + * Empty query response message should be treated same as * Command complete message. When we receive the Command * complete message, we unset the query in progress flag if * operated in streaming replication mode. So we unset the @@ -2718,19 +2800,19 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, pool_unset_query_in_progress(); break; - case 'T': /* RowDescription */ + case 'T': /* RowDescription */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; - case 'n': /* NoData */ + case 'n': /* NoData */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); break; - case 's': /* PortalSuspended */ + case 's': /* PortalSuspended */ status = SimpleForwardToFrontend(kind, frontend, backend); if (pool_is_doing_extended_query_message()) pool_unset_query_in_progress(); @@ -2745,70 +2827,71 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, { switch (kind) { - case 'A': /* NotificationResponse */ + case 'A': /* NotificationResponse */ status = NotificationResponse(frontend, backend); break; - case 'B': /* BinaryRow */ + case 'B': /* BinaryRow */ status = BinaryRow(frontend, backend, *num_fields); break; - case 'C': /* CompletedResponse */ + case 'C': /* CompletedResponse */ status = CompletedResponse(frontend, backend); break; - case 'D': /* AsciiRow */ + case 'D': /* AsciiRow */ status = AsciiRow(frontend, backend, *num_fields); break; - case 'E': /* ErrorResponse */ + case 'E': /* ErrorResponse */ status = ErrorResponse(frontend, backend); if (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) != 'I') pool_set_failed_transaction(); break; - case 'G': /* CopyInResponse */ + case 'G': /* CopyInResponse */ status = CopyInResponse(frontend, backend); break; - case 'H': /* CopyOutResponse */ + case 'H': /* CopyOutResponse */ status = CopyOutResponse(frontend, backend); break; - case 'I': /* EmptyQueryResponse */ + case 'I': /* EmptyQueryResponse */ EmptyQueryResponse(frontend, backend); break; - case 'N': /* NoticeResponse */ + case 'N': /* NoticeResponse */ NoticeResponse(frontend, backend); break; - case 'P': /* CursorResponse */ + case 'P': /* CursorResponse */ status = CursorResponse(frontend, backend); break; - case 'T': /* RowDescription */ + case 'T': /* RowDescription */ status = RowDescription(frontend, backend, num_fields); break; - case 'V': /* FunctionResultResponse and FunctionVoidResponse */ + case 'V': /* FunctionResultResponse and + * FunctionVoidResponse */ status = FunctionResultResponse(frontend, backend); break; - case 'Z': /* ReadyForQuery */ + case 'Z': /* ReadyForQuery */ status = ReadyForQuery(frontend, backend, true, true); break; default: - ereport(FATAL, - (return_code(1), - errmsg("Unknown message type %c(%02x)", kind, kind))); + ereport(FATAL, + (return_code(1), + errmsg("Unknown message type %c(%02x)", kind, kind))); } } - /* Do we receive ready for query while processing reset - * request? + /* + * Do we receive ready for query while processing reset request? */ if (kind == 'Z' && frontend->no_forward && *state == 1) { @@ -2816,15 +2899,16 @@ POOL_STATUS ProcessBackendResponse(POOL_CONNECTION *frontend, } if (status != POOL_CONTINUE) - ereport(FATAL, - (return_code(2), - errmsg("unable to process backend response for message kind '%c'",kind))); + ereport(FATAL, + (return_code(2), + errmsg("unable to process backend response for message kind '%c'", kind))); return status; } -POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +CopyInResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { POOL_STATUS status; @@ -2841,8 +2925,9 @@ POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, return status; } -POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +POOL_STATUS +CopyOutResponse(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { POOL_STATUS status; @@ -2859,33 +2944,34 @@ POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, return status; } -POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, int copyin) +POOL_STATUS +CopyDataRows(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, int copyin) { - char *string = NULL; - int len; - int i; - int copy_count; + char *string = NULL; + int len; + int i; + int copy_count; #ifdef DEBUG - int j = 0; - char buf[1024]; + int j = 0; + char buf[1024]; #endif - copy_count=0; + copy_count = 0; for (;;) { if (copyin) { if (MAJOR(backend) == PROTO_MAJOR_V3) { - char kind; - char *contents = NULL; + char kind; + char *contents = NULL; pool_read(frontend, &kind, 1); ereport(DEBUG5, - (errmsg("copy data rows"), + (errmsg("copy data rows"), errdetail("read kind from frontend %c(%02x)", kind, kind))); pool_read(frontend, &len, sizeof(len)); @@ -2903,19 +2989,19 @@ POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, } else { - if (pool_config->log_client_messages && copy_count !=0 ) + if (pool_config->log_client_messages && copy_count != 0) ereport(LOG, - (errmsg("CopyData message from frontend."), - errdetail("count: %d", copy_count))); + (errmsg("CopyData message from frontend."), + errdetail("count: %d", copy_count))); if (kind == 'c' && pool_config->log_client_messages) ereport(LOG, - (errmsg("CopyDone message from frontend."))); + (errmsg("CopyDone message from frontend."))); if (kind == 'f' && pool_config->log_client_messages) ereport(LOG, - (errmsg("CopyFail message from frontend."))); + (errmsg("CopyFail message from frontend."))); ereport(DEBUG1, - (errmsg("copy data rows"), - errdetail("invalid copyin kind. expected 'd' got '%c'", kind))); + (errmsg("copy data rows"), + errdetail("invalid copyin kind. expected 'd' got '%c'", kind))); break; } } @@ -2941,7 +3027,7 @@ POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, } else { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2952,20 +3038,20 @@ POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, } if (string == NULL) - ereport(FATAL, - (errmsg("unable to copy data rows"), - errdetail("cannot read string message from backend"))); + ereport(FATAL, + (errmsg("unable to copy data rows"), + errdetail("cannot read string message from backend"))); #ifdef DEBUG strlcpy(buf, string, sizeof(buf)); ereport(DEBUG1, - (errmsg("copy data rows"), + (errmsg("copy data rows"), errdetail("copy line %d %d bytes :%s:", j++, len, buf))); #endif if (copyin) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -2990,17 +3076,17 @@ POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, if (copyin) { - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { pool_flush(CONNECTION(backend, i)); if (synchronize(CONNECTION(backend, i))) - ereport(FATAL, - (return_code(2), - errmsg("unable to copy data rows"), - errdetail("failed to synchronize"))); + ereport(FATAL, + (return_code(2), + errmsg("unable to copy data rows"), + errdetail("failed to synchronize"))); } } } @@ -3014,9 +3100,10 @@ POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, * This function raises intentional error to make backends the same * transaction state. */ -void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) +void +raise_intentional_error_if_need(POOL_CONNECTION_POOL * backend) { - int i; + int i; POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; @@ -3041,8 +3128,8 @@ void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) do_error_command(CONNECTION(backend, PRIMARY_NODE_ID), MAJOR(backend)); } ereport(DEBUG1, - (errmsg("raising intentional error"), - errdetail("generating intentional error to sync backends transaction states"))); + (errmsg("raising intentional error"), + errdetail("generating intentional error to sync backends transaction states"))); } if (REPLICATION && @@ -3054,8 +3141,8 @@ void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) for (i = 0; i < NUM_BACKENDS; i++) { /* - * Send a syntax error query to all backends except the node - * which the original query was sent. + * Send a syntax error query to all backends except the node which + * the original query was sent. */ if (pool_is_node_to_be_sent(query_context, i)) continue; @@ -3065,13 +3152,12 @@ void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) if (VALID_BACKEND(i)) { /* - * We must abort transaction to sync transaction state. - * If the error was caused by an Execute message, - * we must send invalid Execute message to abort - * transaction. + * We must abort transaction to sync transaction state. If the + * error was caused by an Execute message, we must send + * invalid Execute message to abort transaction. * - * Because extended query protocol ignores all - * messages before receiving Sync message inside error state. + * Because extended query protocol ignores all messages before + * receiving Sync message inside error state. */ if (pool_is_doing_extended_query_message()) { @@ -3095,12 +3181,13 @@ void raise_intentional_error_if_need(POOL_CONNECTION_POOL *backend) * detected: 4 *--------------------------------------------------- */ -static int check_errors(POOL_CONNECTION_POOL *backend, int backend_id) +static int +check_errors(POOL_CONNECTION_POOL * backend, int backend_id) { /* - * Check dead lock error on the master node and abort - * transactions on all nodes if so. + * Check dead lock error on the master node and abort transactions on all + * nodes if so. */ if (detect_deadlock_error(CONNECTION(backend, backend_id), MAJOR(backend)) == SPECIFIED_ERROR) return 1; @@ -3155,7 +3242,8 @@ static int check_errors(POOL_CONNECTION_POOL *backend, int backend_id) return 0; } -static void generate_error_message(char *prefix, int specific_error, char *query) +static void +generate_error_message(char *prefix, int specific_error, char *query) { POOL_SESSION_CONTEXT *session_context; @@ -3170,9 +3258,9 @@ static void generate_error_message(char *prefix, int specific_error, char *query "received query cancel error message from master node. query: %s" }; - String *msg; + String *msg; - if (specific_error < 1 || specific_error > sizeof(error_messages)/sizeof(char *)) + if (specific_error < 1 || specific_error > sizeof(error_messages) / sizeof(char *)) { ereport(LOG, (errmsg("generate_error_message: invalid specific_error: %d", specific_error))); @@ -3191,29 +3279,31 @@ static void generate_error_message(char *prefix, int specific_error, char *query /* * Make per DB node statement log */ -void per_node_statement_log(POOL_CONNECTION_POOL *backend, int node_id, char *query) +void +per_node_statement_log(POOL_CONNECTION_POOL * backend, int node_id, char *query) { POOL_CONNECTION_POOL_SLOT *slot = backend->slots[node_id]; if (pool_config->log_per_node_statement) ereport(LOG, - (errmsg("DB node id: %d backend pid: %d statement: %s", node_id, ntohl(slot->pid), query))); + (errmsg("DB node id: %d backend pid: %d statement: %s", node_id, ntohl(slot->pid), query))); } /* * Check kind and produce error message * All data read in this function is returned to stream. */ -void per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, char *query, char *prefix, bool unread) +void +per_node_error_log(POOL_CONNECTION_POOL * backend, int node_id, char *query, char *prefix, bool unread) { POOL_CONNECTION_POOL_SLOT *slot = backend->slots[node_id]; - char *message; + char *message; if (pool_extract_error_message(true, CONNECTION(backend, node_id), MAJOR(backend), true, &message) == 1) { ereport(LOG, - (errmsg("%s: DB node id: %d backend pid: %d statement: \"%s\" message: \"%s\"", - prefix, node_id, ntohl(slot->pid), query, message))); + (errmsg("%s: DB node id: %d backend pid: %d statement: \"%s\" message: \"%s\"", + prefix, node_id, ntohl(slot->pid), query, message))); pfree(message); } } @@ -3223,17 +3313,17 @@ void per_node_error_log(POOL_CONNECTION_POOL *backend, int node_id, char *query, * message is not yet parsed on the primary/master node but parsed on other * node. Caller must provide the parse message data as "message". */ -static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - POOL_SENT_MESSAGE *message, - POOL_SENT_MESSAGE *bind_message) +static POOL_STATUS parse_before_bind(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + POOL_SENT_MESSAGE * message, + POOL_SENT_MESSAGE * bind_message) { - int i; - int len = message->len; - char kind = '\0'; - char *contents = message->contents; - bool parse_was_sent = false; - bool backup[MAX_NUM_BACKENDS]; + int i; + int len = message->len; + char kind = '\0'; + char *contents = message->contents; + bool parse_was_sent = false; + bool backup[MAX_NUM_BACKENDS]; POOL_QUERY_CONTEXT *qc = message->query_context; memcpy(backup, qc->where_to_send, sizeof(qc->where_to_send)); @@ -3244,12 +3334,14 @@ static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, { POOL_PENDING_MESSAGE *pmsg; POOL_QUERY_CONTEXT *new_qc; - char message_body[1024]; - int offset; - int message_len; + char message_body[1024]; + int offset; + int message_len; - /* we are in streaming replication mode and the parse message has not - * been sent to primary yet */ + /* + * we are in streaming replication mode and the parse message has + * not been sent to primary yet + */ /* Prepare modified query context */ new_qc = pool_query_context_shallow_copy(qc); @@ -3257,7 +3349,8 @@ static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, new_qc->where_to_send[PRIMARY_NODE_ID] = 1; new_qc->virtual_master_node_id = PRIMARY_NODE_ID; - /* Before sending the parse message to the primary, we need to + /* + * Before sending the parse message to the primary, we need to * close the named statement. Otherwise we will get an error from * backend if the named statement already exists. This could * happend if parse_before_bind is called with a bind message @@ -3268,16 +3361,16 @@ static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, * overwritten anytime. */ message_body[0] = 'S'; - offset = strlen(bind_message->contents)+1; + offset = strlen(bind_message->contents) + 1; ereport(DEBUG1, (errmsg("parse before bind"), - errdetail("close statement: %s", bind_message->contents+offset))); + errdetail("close statement: %s", bind_message->contents + offset))); if (bind_message->contents[offset] != '\0') { - message_len = 1 + strlen(bind_message->contents+offset) + 1; - StrNCpy(message_body+1, bind_message->contents+offset, sizeof(message_body)-1); + message_len = 1 + strlen(bind_message->contents + offset) + 1; + StrNCpy(message_body + 1, bind_message->contents + offset, sizeof(message_body) - 1); pool_extended_send_and_wait(qc, "C", message_len, message_body, 1, PRIMARY_NODE_ID, false); /* Add pending message */ pmsg = pool_pending_message_create('C', message_len, message_body); @@ -3384,23 +3477,25 @@ static POOL_STATUS parse_before_bind(POOL_CONNECTION *frontend, * of this function. Subsequent calls to this function will overwrite * the memory. */ -static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int *number_of_nodes) +static int * +find_victim_nodes(int *ntuples, int nmembers, int master_node, int *number_of_nodes) { - static int victim_nodes[MAX_NUM_BACKENDS]; - static int votes[MAX_NUM_BACKENDS]; - int maxvotes; - int majority_ntuples; - int me; - int cnt; - int healthy_nodes; - int i, j; + static int victim_nodes[MAX_NUM_BACKENDS]; + static int votes[MAX_NUM_BACKENDS]; + int maxvotes; + int majority_ntuples; + int me; + int cnt; + int healthy_nodes; + int i, + j; healthy_nodes = 0; *number_of_nodes = 0; maxvotes = 0; majority_ntuples = 0; - for (i=0;i<nmembers;i++) + for (i = 0; i < nmembers; i++) { me = ntuples[i]; @@ -3414,7 +3509,7 @@ static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int * healthy_nodes++; votes[i] = 1; - for (j=0;j<nmembers;j++) + for (j = 0; j < nmembers; j++) { if (i != j && me == ntuples[j]) { @@ -3437,8 +3532,8 @@ static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int * return NULL; /* - * If master node is specified, let it and others who has same - * ntuples win. + * If master node is specified, let it and others who has same ntuples + * win. */ majority_ntuples = ntuples[master_node]; } @@ -3446,7 +3541,7 @@ static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int * { /* Find number of majority */ cnt = 0; - for (i=0;i<nmembers;i++) + for (i = 0; i < nmembers; i++) { if (votes[i] == maxvotes) { @@ -3471,7 +3566,7 @@ static int* find_victim_nodes(int *ntuples, int nmembers, int master_node, int * } /* Make victim nodes list */ - for (i=0;i<nmembers;i++) + for (i = 0; i < nmembers; i++) { if (ntuples[i] >= 0 && ntuples[i] != majority_ntuples) { @@ -3523,6 +3618,7 @@ flatten_set_variable_args(const char *name, List *args) if (IsA(arg, TypeCast)) { TypeCast *tc = (TypeCast *) arg; + arg = tc->arg; } @@ -3545,7 +3641,7 @@ flatten_set_variable_args(const char *name, List *args) break; default: ereport(ERROR, (errmsg("unrecognized node type: %d", - (int) nodeTag(&con->val)))); + (int) nodeTag(&con->val)))); break; } } @@ -3556,15 +3652,16 @@ flatten_set_variable_args(const char *name, List *args) /* Called when sync message is received. * Wait till ready for query received. */ -static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL *backend) +static void +pool_wait_till_ready_for_query(POOL_CONNECTION_POOL * backend) { - char kind; - int len; - int poplen; - char *buf; - int i; + char kind; + int len; + int poplen; + char *buf; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { @@ -3576,10 +3673,10 @@ static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL *backend) pool_push(CONNECTION(backend, i), &kind, sizeof(kind)); pool_read(CONNECTION(backend, i), &len, sizeof(len)); pool_push(CONNECTION(backend, i), &len, sizeof(len)); - if ((ntohl(len)-sizeof(len)) > 0) + if ((ntohl(len) - sizeof(len)) > 0) { - buf = pool_read2(CONNECTION(backend, i), ntohl(len)-sizeof(len)); - pool_push(CONNECTION(backend, i), buf, ntohl(len)-sizeof(len)); + buf = pool_read2(CONNECTION(backend, i), ntohl(len) - sizeof(len)); + pool_push(CONNECTION(backend, i), buf, ntohl(len) - sizeof(len)); } if (kind == 'Z') /* Ready for query? */ @@ -3602,29 +3699,29 @@ static void pool_wait_till_ready_for_query(POOL_CONNECTION_POOL *backend) * not received yet, continue to read data from frontend until a sync message * is read. */ -static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend) +static void +pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend) { POOL_PENDING_MESSAGE *pmsg; - int i; + int i; if (!pool_is_doing_extended_query_message() || !SL_MODE) return; /* - * Check to see if we aready received a sync - * message. If not, call ProcessFrontendResponse() to - * get the sync message from client. + * Check to see if we aready received a sync message. If not, call + * ProcessFrontendResponse() to get the sync message from client. */ pmsg = pool_pending_message_get(POOL_SYNC); if (pmsg == NULL) { - char kind; - int len; + char kind; + int len; POOL_PENDING_MESSAGE *msg; - char *contents = NULL; + char *contents = NULL; - for(;;) + for (;;) { pool_read(frontend, &kind, sizeof(kind)); pool_read(frontend, &len, sizeof(len)); @@ -3665,13 +3762,13 @@ static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *fronte pool_pending_message_reset_previous_message(); /* Discard read buffer execpt "Ready for query" */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) { - char kind; - int len; - int sts; + char kind; + int len; + int sts; while (!pool_read_buffer_is_empty(CONNECTION(backend, i))) { @@ -3697,12 +3794,12 @@ static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *fronte { /* Read and discard packet */ pool_read(CONNECTION(backend, i), &len, sizeof(len)); - if ((ntohl(len)-sizeof(len)) > 0) + if ((ntohl(len) - sizeof(len)) > 0) { - pool_read2(CONNECTION(backend, i), ntohl(len)-sizeof(len)); + pool_read2(CONNECTION(backend, i), ntohl(len) - sizeof(len)); } ereport(DEBUG1, - (errmsg("pool_discard_except_sync_and_ready_for_query: discarding packet %c (len:%lu) of backend:%d", kind, ntohl(len)-sizeof(len), i))); + (errmsg("pool_discard_except_sync_and_ready_for_query: discarding packet %c (len:%lu) of backend:%d", kind, ntohl(len) - sizeof(len), i))); } } } @@ -3713,10 +3810,11 @@ static void pool_discard_except_sync_and_ready_for_query(POOL_CONNECTION *fronte * Handle misc treatment when a command successfully completed. * Preconditions: query is in progress. The command is succeeded. */ -void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +pool_at_command_success(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - Node *node; - char *query; + Node *node; + char *query; /* Sanity checks */ if (!pool_is_query_in_progress()) @@ -3748,14 +3846,13 @@ void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba } /* - * If the query was BEGIN/START TRANSACTION, clear the - * history that we had a writing command in the transaction - * and forget the transaction isolation level. + * If the query was BEGIN/START TRANSACTION, clear the history that we had + * a writing command in the transaction and forget the transaction + * isolation level. * - * XXX If BEGIN is received while we are already in an - * explicit transaction, the command *successes* - * (just with a NOTICE message). In this case we lose - * "writing_transaction" etc. info. + * XXX If BEGIN is received while we are already in an explicit + * transaction, the command *successes* (just with a NOTICE message). In + * this case we lose "writing_transaction" etc. info. */ if (is_start_transaction_query(node)) { @@ -3767,11 +3864,9 @@ void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba } /* - * If the query was COMMIT/ABORT, clear the history - * that we had a writing command in the transaction - * and forget the transaction isolation level. This - * is necessary if succeeding transaction is not an - * explicit one. + * If the query was COMMIT/ABORT, clear the history that we had a writing + * command in the transaction and forget the transaction isolation level. + * This is necessary if succeeding transaction is not an explicit one. */ else if (is_commit_or_rollback_query(node)) { @@ -3783,9 +3878,9 @@ void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba } /* - * SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET - * SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL - * SERIALIZABLE, remember it. + * SET TRANSACTION ISOLATION LEVEL SERIALIZABLE or SET SESSION + * CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE, remember + * it. */ else if (is_set_transaction_serializable(node)) { @@ -3793,10 +3888,9 @@ void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba } /* - * If 2PC commands has been executed, automatically close - * transactions on standbys if there is any open - * transaction since 2PC commands close transaction on - * primary. + * If 2PC commands has been executed, automatically close transactions on + * standbys if there is any open transaction since 2PC commands close + * transaction on primary. */ else if (is_2pc_transaction_query(node)) { @@ -3813,8 +3907,9 @@ void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba if (TSTATE(backend, MASTER_SLAVE ? PRIMARY_NODE_ID : REAL_MASTER_NODE_ID) == 'T' || pool_config->disable_load_balance_on_write == DLBOW_ALWAYS) { - /* However, if the query is "SET TRANSACTION READ ONLY" or its variant, - * don't set it. + /* + * However, if the query is "SET TRANSACTION READ ONLY" or its + * variant, don't set it. */ if (!pool_is_transaction_read_only(node)) { @@ -3826,14 +3921,14 @@ void pool_at_command_success(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba } /* - * If the query was CREATE TEMP TABLE, discard - * temp table relcache because we might have had - * persistent table relation cache which has table - * name as the temp table. + * If the query was CREATE TEMP TABLE, discard temp table relcache + * because we might have had persistent table relation cache which has + * table name as the temp table. */ if (IsA(node, CreateStmt)) { - CreateStmt *create_table_stmt = (CreateStmt *)node; + CreateStmt *create_table_stmt = (CreateStmt *) node; + if (create_table_stmt->relation->relpersistence == 't') discard_temp_table_relcache(); } diff --git a/src/query_cache/pool_memqcache.c b/src/query_cache/pool_memqcache.c index 32c541a41..1d8745b6d 100644 --- a/src/query_cache/pool_memqcache.c +++ b/src/query_cache/pool_memqcache.c @@ -60,77 +60,78 @@ memcached_st *memc; #endif -static char* encode_key(const char *s, char *buf, POOL_CONNECTION_POOL *backend); +static char *encode_key(const char *s, char *buf, POOL_CONNECTION_POOL * backend); #ifdef DEBUG static void dump_cache_data(const char *data, size_t len); #endif -static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *data, size_t datalen, int num_oids, int *oids); -static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, char **buf, size_t *len); -static int send_cached_messages(POOL_CONNECTION *frontend, const char *qcache, int qcachelen); -static void send_message(POOL_CONNECTION *conn, char kind, int len, const char *data); +static int pool_commit_cache(POOL_CONNECTION_POOL * backend, char *query, char *data, size_t datalen, int num_oids, int *oids); +static int pool_fetch_cache(POOL_CONNECTION_POOL * backend, const char *query, char **buf, size_t *len); +static int send_cached_messages(POOL_CONNECTION * frontend, const char *qcache, int qcachelen); +static void send_message(POOL_CONNECTION * conn, char kind, int len, const char *data); #ifdef USE_MEMCACHED -static int delete_cache_on_memcached(const char *key); +static int delete_cache_on_memcached(const char *key); #endif -static int pool_get_dml_table_oid(int **oid); -static int pool_get_dropdb_table_oids(int **oids, int dboid); +static int pool_get_dml_table_oid(int **oid); +static int pool_get_dropdb_table_oids(int **oids, int dboid); static void pool_discard_dml_table_oid(void); static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlink, int dboid); -static int pool_get_database_oid(void); -static void pool_add_table_oid_map(POOL_CACHEKEY *cachkey, int num_table_oids, int *table_oids); +static int pool_get_database_oid(void); +static void pool_add_table_oid_map(POOL_CACHEKEY * cachkey, int num_table_oids, int *table_oids); static void pool_reset_memqcache_buffer(void); -static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char *data, int size); -static POOL_CACHEID *pool_find_item_on_shmem_cache(POOL_QUERY_HASH *query_hash); -static char *pool_get_item_shmem_cache(POOL_QUERY_HASH *query_hash, int *size, int *sts); -static POOL_QUERY_CACHE_ARRAY * pool_add_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array, POOL_TEMP_QUERY_CACHE *cache); -static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char kind, char *data, int data_len); -static void pool_add_oids_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, int num_oids, int *oids); -static POOL_INTERNAL_BUFFER *pool_create_buffer(void); -static void pool_discard_buffer(POOL_INTERNAL_BUFFER *buffer); -static void pool_add_buffer(POOL_INTERNAL_BUFFER *buffer, void *data, size_t len); -static void *pool_get_buffer(POOL_INTERNAL_BUFFER *buffer, size_t *len); +static POOL_CACHEID * pool_add_item_shmem_cache(POOL_QUERY_HASH * query_hash, char *data, int size); +static POOL_CACHEID * pool_find_item_on_shmem_cache(POOL_QUERY_HASH * query_hash); +static char *pool_get_item_shmem_cache(POOL_QUERY_HASH * query_hash, int *size, int *sts); +static POOL_QUERY_CACHE_ARRAY * pool_add_query_cache_array(POOL_QUERY_CACHE_ARRAY * cache_array, POOL_TEMP_QUERY_CACHE * cache); +static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache, char kind, char *data, int data_len); +static void pool_add_oids_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache, int num_oids, int *oids); +static POOL_INTERNAL_BUFFER * pool_create_buffer(void); +static void pool_discard_buffer(POOL_INTERNAL_BUFFER * buffer); +static void pool_add_buffer(POOL_INTERNAL_BUFFER * buffer, void *data, size_t len); +static void *pool_get_buffer(POOL_INTERNAL_BUFFER * buffer, size_t *len); #ifdef NOT_USED -static char *pool_get_buffer_pointer(POOL_INTERNAL_BUFFER *buffer); +static char *pool_get_buffer_pointer(POOL_INTERNAL_BUFFER * buffer); #endif static char *pool_get_current_cache_buffer(size_t *len); -static size_t pool_get_buffer_length(POOL_INTERNAL_BUFFER *buffer); +static size_t pool_get_buffer_length(POOL_INTERNAL_BUFFER * buffer); static void pool_check_and_discard_cache_buffer(int num_oids, int *oids); static void pool_set_memqcache_blocks(int num_blocks); -static int pool_get_memqcache_blocks(void); +static int pool_get_memqcache_blocks(void); static void *pool_memory_cache_address(void); static void pool_reset_fsmm(size_t size); static void *pool_fsmm_address(void); static void pool_update_fsmm(POOL_CACHE_BLOCKID blockid, size_t free_space); static POOL_CACHE_BLOCKID pool_get_block(size_t free_space); -static POOL_CACHE_ITEM_HEADER *pool_cache_item_header(POOL_CACHEID *cacheid); -static int pool_init_cache_block(POOL_CACHE_BLOCKID blockid); +static POOL_CACHE_ITEM_HEADER * pool_cache_item_header(POOL_CACHEID * cacheid); +static int pool_init_cache_block(POOL_CACHE_BLOCKID blockid); #if NOT_USED static void pool_wipe_out_cache_block(POOL_CACHE_BLOCKID blockid); #endif -static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid); +static int pool_delete_item_shmem_cache(POOL_CACHEID * cacheid); static char *block_address(int blockid); -static POOL_CACHE_ITEM_POINTER *item_pointer(char *block, int i); -static POOL_CACHE_ITEM_HEADER *item_header(char *block, int i); +static POOL_CACHE_ITEM_POINTER * item_pointer(char *block, int i); +static POOL_CACHE_ITEM_HEADER * item_header(char *block, int i); static POOL_CACHE_BLOCKID pool_reuse_block(void); #ifdef SHMEMCACHE_DEBUG static void dump_shmem_cache(POOL_CACHE_BLOCKID blockid); #endif -static int pool_hash_reset(int nelements); -static int pool_hash_insert(POOL_QUERY_HASH *key, POOL_CACHEID *cacheid, bool update); -static uint32 create_hash_key(POOL_QUERY_HASH *key); +static int pool_hash_reset(int nelements); +static int pool_hash_insert(POOL_QUERY_HASH * key, POOL_CACHEID * cacheid, bool update); +static uint32 create_hash_key(POOL_QUERY_HASH * key); static volatile POOL_HASH_ELEMENT *get_new_hash_element(void); -static void put_back_hash_element(volatile POOL_HASH_ELEMENT *element); +static void put_back_hash_element(volatile POOL_HASH_ELEMENT * element); static bool is_free_hash_element(void); -static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qcachelen); +static void inject_cached_message(POOL_CONNECTION * backend, char *qcache, int qcachelen); /* * Connect to Memcached */ -int memcached_connect(void) +int +memcached_connect(void) { - char *memqcache_memcached_host; - int memqcache_memcached_port; + char *memqcache_memcached_host; + int memqcache_memcached_port; #ifdef USE_MEMCACHED memcached_server_st *servers; memcached_return rc; @@ -146,7 +147,7 @@ int memcached_connect(void) memqcache_memcached_port = pool_config->memqcache_memcached_port; ereport(DEBUG1, - (errmsg("connecting to memcached on Host:\"%s:%d\"", memqcache_memcached_host,memqcache_memcached_port))); + (errmsg("connecting to memcached on Host:\"%s:%d\"", memqcache_memcached_host, memqcache_memcached_port))); #ifdef USE_MEMCACHED memc = memcached_create(NULL); @@ -159,8 +160,8 @@ int memcached_connect(void) if (rc != MEMCACHED_SUCCESS) { ereport(WARNING, - (errmsg("failed to connect to memcached, server push error:\"%s\"\n", memcached_strerror(memc, rc)))); - memc = (memcached_st *)-1; + (errmsg("failed to connect to memcached, server push error:\"%s\"\n", memcached_strerror(memc, rc)))); + memc = (memcached_st *) - 1; return -1; } memcached_server_list_free(servers); @@ -175,7 +176,8 @@ int memcached_connect(void) /* * Disconnect to Memcached */ -void memcached_disconnect (void) +void +memcached_disconnect(void) { #ifdef USE_MEMCACHED if (!memc) @@ -192,10 +194,11 @@ void memcached_disconnect (void) /* * Register buffer data for query cache in memory cache */ -void memqcache_register(char kind, - POOL_CONNECTION *frontend, - char *data, - int data_len) +void +memqcache_register(char kind, + POOL_CONNECTION * frontend, + char *data, + int data_len) { POOL_TEMP_QUERY_CACHE *cache; POOL_SESSION_CONTEXT *session_context; @@ -209,7 +212,8 @@ void memqcache_register(char kind, if (session_context && pool_is_query_in_progress()) { - char *query = pool_get_query_string(); + char *query = pool_get_query_string(); + query_context = session_context->query_context; if (query) @@ -223,14 +227,15 @@ void memqcache_register(char kind, /* * Commit SELECT results to cache storage. */ -static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *data, size_t datalen, int num_oids, int *oids) +static int +pool_commit_cache(POOL_CONNECTION_POOL * backend, char *query, char *data, size_t datalen, int num_oids, int *oids) { #ifdef USE_MEMCACHED memcached_return rc; #endif POOL_CACHEKEY cachekey; - char tmpkey[MAX_KEY]; - time_t memqcache_expire; + char tmpkey[MAX_KEY]; + time_t memqcache_expire; /* * get_buflen() will return -1 if query result exceeds memqcache_maxcache @@ -246,7 +251,7 @@ static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *d return -1; } ereport(DEBUG1, - (errmsg("commiting SELECT results to cache storage"), + (errmsg("commiting SELECT results to cache storage"), errdetail("Query=\"%s\"", query))); #ifdef DEBUG @@ -256,14 +261,14 @@ static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *d /* encode md5key for memcached */ encode_key(query, tmpkey, backend); ereport(DEBUG2, - (errmsg("commiting SELECT results to cache storage"), + (errmsg("commiting SELECT results to cache storage"), errdetail("search key : \"%s\"", tmpkey))); memcpy(cachekey.hashkey, tmpkey, 32); memqcache_expire = pool_config->memqcache_expire; ereport(DEBUG1, - (errmsg("commiting SELECT results to cache storage"), + (errmsg("commiting SELECT results to cache storage"), errdetail("memqcache_expire = %ld", memqcache_expire))); if (pool_is_shmem_cache()) @@ -278,7 +283,7 @@ static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *d if (cacheid != NULL) { ereport(DEBUG1, - (errmsg("commiting SELECT results to cache storage"), + (errmsg("commiting SELECT results to cache storage"), errdetail("item already exists"))); return 0; @@ -295,9 +300,9 @@ static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *d else { ereport(DEBUG2, - (errmsg("commiting SELECT results to cache storage"), - errdetail("blockid: %d itemid: %d", - cacheid->blockid, cacheid->itemid))); + (errmsg("commiting SELECT results to cache storage"), + errdetail("blockid: %d itemid: %d", + cacheid->blockid, cacheid->itemid))); } cachekey.cacheid.blockid = cacheid->blockid; cachekey.cacheid.itemid = cacheid->itemid; @@ -308,15 +313,15 @@ static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *d else { rc = memcached_set(memc, tmpkey, 32, - data, datalen, (time_t)memqcache_expire, 0); + data, datalen, (time_t) memqcache_expire, 0); if (rc != MEMCACHED_SUCCESS) { ereport(WARNING, - (errmsg("cache commit failed with error:\"%s\"",memcached_strerror(memc, rc)))); + (errmsg("cache commit failed with error:\"%s\"", memcached_strerror(memc, rc)))); return -1; } ereport(DEBUG1, - (errmsg("commiting SELECT results to cache storage"), + (errmsg("commiting SELECT results to cache storage"), errdetail("set cache succeeded"))); } #endif @@ -332,31 +337,32 @@ static int pool_commit_cache(POOL_CONNECTION_POOL *backend, char *query, char *d /* * Fetch from memory cache. * Return: - * 0: fetch success, + * 0: fetch success, * 1: not found */ -static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, char **buf, size_t *len) +static int +pool_fetch_cache(POOL_CONNECTION_POOL * backend, const char *query, char **buf, size_t *len) { - char *ptr; - char tmpkey[MAX_KEY]; - int sts; - char *p; + char *ptr; + char tmpkey[MAX_KEY]; + int sts; + char *p; if (strlen(query) <= 0) ereport(ERROR, - (errmsg("fetching from cache storage, no query"))); + (errmsg("fetching from cache storage, no query"))); /* encode md5key for memcached */ encode_key(query, tmpkey, backend); ereport(DEBUG1, - (errmsg("fetching from cache storage"), + (errmsg("fetching from cache storage"), errdetail("search key \"%s\"", tmpkey))); if (pool_is_shmem_cache()) { POOL_QUERY_HASH query_hash; - int mylen; + int mylen; memcpy(query_hash.query_hash, tmpkey, sizeof(query_hash.query_hash)); @@ -364,7 +370,7 @@ static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, ch if (ptr == NULL) { ereport(DEBUG1, - (errmsg("fetching from cache storage"), + (errmsg("fetching from cache storage"), errdetail("cache not found on shared memory"))); return 1; @@ -384,7 +390,8 @@ static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, ch if (rc != MEMCACHED_NOTFOUND) { ereport(LOG, - (errmsg("fetching from cache storage, memcached_get failed with error: \"%s\"", memcached_strerror(memc, rc)))); + (errmsg("fetching from cache storage, memcached_get failed with error: \"%s\"", memcached_strerror(memc, rc)))); + /* * Turn off memory cache support to prevent future errors. */ @@ -396,8 +403,8 @@ static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, ch { /* Not found */ ereport(DEBUG1, - (errmsg("fetching from cache storage"), - errdetail("cache item not found for key: \"%s\" and query:\"%s\"",tmpkey,query))); + (errmsg("fetching from cache storage"), + errdetail("cache item not found for key: \"%s\" and query:\"%s\"", tmpkey, query))); return 1; } } @@ -406,7 +413,7 @@ static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, ch else { ereport(ERROR, - (errmsg("memcached support is not enabled"))); + (errmsg("memcached support is not enabled"))); } #endif @@ -420,7 +427,7 @@ static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, ch } ereport(DEBUG1, - (errmsg("fetching from cache storage"), + (errmsg("fetching from cache storage"), errdetail("query=\"%s\" len:%zd", query, *len))); #ifdef DEBUG dump_cache_data(p, *len); @@ -435,35 +442,36 @@ static int pool_fetch_cache(POOL_CONNECTION_POOL *backend, const char *query, ch * encode key. * create cache key as md5(username + query string + database name) */ -static char* encode_key(const char *s, char *buf, POOL_CONNECTION_POOL *backend) +static char * +encode_key(const char *s, char *buf, POOL_CONNECTION_POOL * backend) { - char* strkey; - int u_length; - int d_length; - int q_length; - int length; + char *strkey; + int u_length; + int d_length; + int q_length; + int length; u_length = strlen(backend->info->user); ereport(DEBUG1, - (errmsg("memcache encode key"), - errdetail("username: \"%s\" database_name: \"%s\"", backend->info->user,backend->info->database))); + (errmsg("memcache encode key"), + errdetail("username: \"%s\" database_name: \"%s\"", backend->info->user, backend->info->database))); d_length = strlen(backend->info->database); q_length = strlen(s); ereport(DEBUG1, - (errmsg("memcache encode key"), + (errmsg("memcache encode key"), errdetail("query: \"%s\"", s))); length = u_length + d_length + q_length + 1; - strkey = (char*)palloc(sizeof(char) * length); + strkey = (char *) palloc(sizeof(char) * length); snprintf(strkey, length, "%s%s%s", backend->info->user, s, backend->info->database); pool_md5_hash(strkey, strlen(strkey), buf); ereport(DEBUG1, - (errmsg("memcache encode key"), + (errmsg("memcache encode key"), errdetail("`%s' -> `%s'", strkey, buf))); pfree(strkey); return buf; @@ -473,29 +481,30 @@ static char* encode_key(const char *s, char *buf, POOL_CONNECTION_POOL *backend) /* * dump cache data */ -static void dump_cache_data(const char *data, size_t len) +static void +dump_cache_data(const char *data, size_t len) { - int i; - int plen; - + int i; + int plen; - fprintf(stderr,"shmem: len = %zd\n", len); + + fprintf(stderr, "shmem: len = %zd\n", len); while (len > 0) { - fprintf(stderr,"shmem: kind:%c\n", *data++); + fprintf(stderr, "shmem: kind:%c\n", *data++); len--; memmove(&plen, data, 4); len -= 4; data += 4; plen = ntohl(plen); - fprintf(stderr,"shmem: len:%d\n", plen); + fprintf(stderr, "shmem: len:%d\n", plen); plen -= 4; fprintf(stderr, "shmem: "); - for (i=0;i<plen;i++) + for (i = 0; i < plen; i++) { - fprintf(stderr, "%02x ", (unsigned char)(*data++)); + fprintf(stderr, "%02x ", (unsigned char) (*data++)); len--; } fprintf(stderr, "\n"); @@ -506,23 +515,24 @@ static void dump_cache_data(const char *data, size_t len) /* * send cached messages */ -static int send_cached_messages(POOL_CONNECTION *frontend, const char *qcache, int qcachelen) +static int +send_cached_messages(POOL_CONNECTION * frontend, const char *qcache, int qcachelen) { - int msg = 0; - int i = 0; - int is_prepared_stmt = 0; - int len; + int msg = 0; + int i = 0; + int is_prepared_stmt = 0; + int len; const char *p; while (i < qcachelen) { - char tmpkind; - int tmplen; + char tmpkind; + int tmplen; tmpkind = qcache[i]; i++; - memcpy(&tmplen, qcache+i, sizeof(tmplen)); + memcpy(&tmplen, qcache + i, sizeof(tmplen)); i += sizeof(tmplen); len = ntohl(tmplen); p = qcache + i; @@ -536,8 +546,8 @@ static int send_cached_messages(POOL_CONNECTION *frontend, const char *qcache, i } /* - * In the prepared statement execution, there is no need to send - * 'T' response to the frontend. + * In the prepared statement execution, there is no need to send 'T' + * response to the frontend. */ if (is_prepared_stmt && tmpkind == 'T') { @@ -546,7 +556,7 @@ static int send_cached_messages(POOL_CONNECTION *frontend, const char *qcache, i /* send message to frontend */ ereport(DEBUG1, - (errmsg("memcache: sending cached messages: '%c' len: %d", tmpkind, len))); + (errmsg("memcache: sending cached messages: '%c' len: %d", tmpkind, len))); send_message(frontend, tmpkind, len, p); msg++; @@ -558,7 +568,8 @@ static int send_cached_messages(POOL_CONNECTION *frontend, const char *qcache, i /* * send message to frontend */ -static void send_message(POOL_CONNECTION *conn, char kind, int len, const char *data) +static void +send_message(POOL_CONNECTION * conn, char kind, int len, const char *data) { ereport(DEBUG2, (errmsg("memcache: sending messages: kind '%c', len=%d, data=%p", kind, len, data))); @@ -569,14 +580,15 @@ static void send_message(POOL_CONNECTION *conn, char kind, int len, const char * pool_write(conn, &len, sizeof(len)); len = ntohl(len); - pool_write(conn, (void *)data, len-sizeof(len)); + pool_write(conn, (void *) data, len - sizeof(len)); } #ifdef USE_MEMCACHED /* * delete query cache on memcached */ -static int delete_cache_on_memcached(const char *key) +static int +delete_cache_on_memcached(const char *key) { memcached_return rc; @@ -586,16 +598,16 @@ static int delete_cache_on_memcached(const char *key) /* delete cache data on memcached. key is md5 hash query */ - rc= memcached_delete(memc, key, 32, (time_t)0); + rc = memcached_delete(memc, key, 32, (time_t) 0); /* delete cache data on memcached is failed */ - if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) - { + if (rc != MEMCACHED_SUCCESS && rc != MEMCACHED_BUFFERED) + { ereport(LOG, (errmsg("failed to delete cache on memcached, error:\"%s\"", memcached_strerror(memc, rc)))); - return 0; - } - return 1; + return 0; + } + return 1; } #endif @@ -603,34 +615,35 @@ static int delete_cache_on_memcached(const char *key) /* * Fetch SELECT data from cache if possible. */ -POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, - POOL_CONNECTION_POOL *backend, - char *contents, bool *foundp) +POOL_STATUS +pool_fetch_from_memory_cache(POOL_CONNECTION * frontend, + POOL_CONNECTION_POOL * backend, + char *contents, bool *foundp) { - char *qcache; - size_t qcachelen; - int sts; + char *qcache; + size_t qcachelen; + int sts; pool_sigset_t oldmask; ereport(DEBUG1, (errmsg("pool_fetch_from_memory_cache called"))); *foundp = false; - - POOL_SETMASK2(&BlockSig, &oldmask); + + POOL_SETMASK2(&BlockSig, &oldmask); pool_shmem_lock(); - PG_TRY(); - { - sts = pool_fetch_cache(backend, contents, &qcache, &qcachelen); - } - PG_CATCH(); - { - pool_shmem_unlock(); - POOL_SETMASK(&oldmask); - PG_RE_THROW(); - } - PG_END_TRY(); + PG_TRY(); + { + sts = pool_fetch_cache(backend, contents, &qcache, &qcachelen); + } + PG_CATCH(); + { + pool_shmem_unlock(); + POOL_SETMASK(&oldmask); + PG_RE_THROW(); + } + PG_END_TRY(); pool_shmem_unlock(); POOL_SETMASK(&oldmask); @@ -677,7 +690,7 @@ POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, * We keep previous transaction state. */ state = MASTER(backend)->tstate; - send_message(frontend, 'Z', 5, (char *)&state); + send_message(frontend, 'Z', 5, (char *) &state); } if (!pool_is_doing_extended_query_message() || !SL_MODE) @@ -707,9 +720,10 @@ POOL_STATUS pool_fetch_from_memory_cache(POOL_CONNECTION *frontend, * SELECT. Just check if the query starts with SELECT or WITH. This * can be used before parse tree is available. */ -bool pool_is_likely_select(char *query) +bool +pool_is_likely_select(char *query) { - bool do_continue = false; + bool do_continue = false; if (query == NULL) return false; @@ -720,15 +734,15 @@ bool pool_is_likely_select(char *query) while (*query && isspace(*query)) query++; } - if (! *query) + if (!*query) { return false; } /* - * Get rid of head comment. - * It is sure that the query is in correct format, because the parser - * has rejected bad queries such as the one with not-ended comment. + * Get rid of head comment. It is sure that the query is in correct + * format, because the parser has rejected bad queries such as the one + * with not-ended comment. */ while (*query) { @@ -791,10 +805,11 @@ bool pool_is_likely_select(char *query) * the query and "query" is the query string. * The query must be SELECT or WITH. */ -bool pool_is_allow_to_cache(Node *node, char *query) +bool +pool_is_allow_to_cache(Node *node, char *query) { - int i = 0; - int num_oids = -1; + int i = 0; + int num_oids = -1; SelectContext ctx; /* @@ -802,12 +817,16 @@ bool pool_is_allow_to_cache(Node *node, char *query) */ if (!strncasecmp(query, NO_QUERY_CACHE, NO_QUERY_CACHE_COMMENT_SZ)) return false; + /* * Check black table list first. */ if (pool_config->num_black_memqcache_table_list > 0) { - /* Extract oids in from clause of SELECT, and check if SELECT to them could be cached. */ + /* + * Extract oids in from clause of SELECT, and check if SELECT to them + * could be cached. + */ num_oids = pool_extract_table_oids_from_select_stmt(node, &ctx); if (num_oids > 0) { @@ -830,8 +849,7 @@ bool pool_is_allow_to_cache(Node *node, char *query) return false; /* - * If SELECT uses non immutable functions, it's not allowed to - * cache. + * If SELECT uses non immutable functions, it's not allowed to cache. */ if (pool_has_non_immutable_function_call(node)) return false; @@ -851,10 +869,11 @@ bool pool_is_allow_to_cache(Node *node, char *query) /* * TABLESAMPLE is not allowed to cache. */ - if (IsA(node, SelectStmt) && ((SelectStmt *)node)->fromClause) + if (IsA(node, SelectStmt) &&((SelectStmt *) node)->fromClause) { - List *tbl_list = ((SelectStmt *)node)->fromClause; + List *tbl_list = ((SelectStmt *) node)->fromClause; ListCell *tbl; + foreach(tbl, tbl_list) { if (IsA(lfirst(tbl), RangeTableSample)) @@ -864,8 +883,8 @@ bool pool_is_allow_to_cache(Node *node, char *query) /* - * If the table is in the while list, allow to cache even if it is - * VIEW or unlogged table. + * If the table is in the while list, allow to cache even if it is VIEW or + * unlogged table. */ if (pool_config->num_white_memqcache_table_list > 0) { @@ -876,7 +895,8 @@ bool pool_is_allow_to_cache(Node *node, char *query) { for (i = 0; i < num_oids; i++) { - char *table = ctx.table_names[i]; + char *table = ctx.table_names[i]; + ereport(DEBUG1, (errmsg("memcache: checking if node is allowed to cache: check table_names[%d] = \"%s\"", i, table))); if (is_view(table) || is_unlogged_table(table)) @@ -912,11 +932,12 @@ bool pool_is_allow_to_cache(Node *node, char *query) /* * Return true If the SELECTed table is in back list. */ -bool pool_is_table_in_black_list(const char *table_name) +bool +pool_is_table_in_black_list(const char *table_name) { if (pool_config->num_black_memqcache_table_list > 0 && - pattern_compare((char *)table_name, BLACKLIST, "black_memqcache_table_list") == 1) + pattern_compare((char *) table_name, BLACKLIST, "black_memqcache_table_list") == 1) { return true; } @@ -927,10 +948,11 @@ bool pool_is_table_in_black_list(const char *table_name) /* * Return true If the SELECTed table is in white list. */ -bool pool_is_table_in_white_list(const char *table_name) +bool +pool_is_table_in_white_list(const char *table_name) { if (pool_config->num_white_memqcache_table_list > 0 && - pattern_compare((char *)table_name, WHITELIST, "white_memqcache_table_list") == 1) + pattern_compare((char *) table_name, WHITELIST, "white_memqcache_table_list") == 1) { return true; } @@ -945,13 +967,14 @@ bool pool_is_table_in_white_list(const char *table_name) * In case of error, returns 0 (InvalidOid). * oids buffer (oidsp) will be discarded by subsequent call. */ -int pool_extract_table_oids(Node *node, int **oidsp) +int +pool_extract_table_oids(Node *node, int **oidsp) { #define POOL_MAX_DML_OIDS 128 - char *table; - static int oids[POOL_MAX_DML_OIDS]; - int num_oids; - int oid; + char *table; + static int oids[POOL_MAX_DML_OIDS]; + int num_oids; + int oid; if (node == NULL) { @@ -965,42 +988,48 @@ int pool_extract_table_oids(Node *node, int **oidsp) if (IsA(node, InsertStmt)) { - InsertStmt *stmt = (InsertStmt *)node; + InsertStmt *stmt = (InsertStmt *) node; + table = make_table_name_from_rangevar(stmt->relation); } else if (IsA(node, UpdateStmt)) { - UpdateStmt *stmt = (UpdateStmt *)node; + UpdateStmt *stmt = (UpdateStmt *) node; + table = make_table_name_from_rangevar(stmt->relation); } else if (IsA(node, DeleteStmt)) { - DeleteStmt *stmt = (DeleteStmt *)node; + DeleteStmt *stmt = (DeleteStmt *) node; + table = make_table_name_from_rangevar(stmt->relation); } #ifdef NOT_USED + /* * We do not handle CREATE TABLE here. It is possible that - * pool_extract_table_oids() is called before CREATE TABLE gets - * executed. + * pool_extract_table_oids() is called before CREATE TABLE gets executed. */ else if (IsA(node, CreateStmt)) { - CreateStmt *stmt = (CreateStmt *)node; + CreateStmt *stmt = (CreateStmt *) node; + table = make_table_name_from_rangevar(stmt->relation); } #endif else if (IsA(node, AlterTableStmt)) { - AlterTableStmt *stmt = (AlterTableStmt *)node; + AlterTableStmt *stmt = (AlterTableStmt *) node; + table = make_table_name_from_rangevar(stmt->relation); } else if (IsA(node, CopyStmt)) { - CopyStmt *stmt = (CopyStmt *)node; + CopyStmt *stmt = (CopyStmt *) node; + if (stmt->is_from) /* COPY FROM? */ { table = make_table_name_from_rangevar(stmt->relation); @@ -1013,18 +1042,19 @@ int pool_extract_table_oids(Node *node, int **oidsp) else if (IsA(node, DropStmt)) { - ListCell *cell; + ListCell *cell; - DropStmt *stmt = (DropStmt *)node; + DropStmt *stmt = (DropStmt *) node; if (stmt->removeType != OBJECT_TABLE) { return 0; } - /* Here, stmt->objects is list of target relation info. The - * first cell of target relation info is a list (possibly) - * consists of database, schema and relation. We need to call + /* + * Here, stmt->objects is list of target relation info. The first + * cell of target relation info is a list (possibly) consists of + * database, schema and relation. We need to call * makeRangeVarFromNameList() before passing to * make_table_name_from_rangevar. Otherwise we get weird excessively * decorated relation name (''table_name''). @@ -1044,16 +1074,16 @@ int pool_extract_table_oids(Node *node, int **oidsp) { oids[num_oids++] = pool_table_name_to_oid(table); ereport(DEBUG1, - (errmsg("memcache: extracting table oids: table: \"%s\" oid:%d", table, oids[num_oids-1]))); + (errmsg("memcache: extracting table oids: table: \"%s\" oid:%d", table, oids[num_oids - 1]))); } } return num_oids; } else if (IsA(node, TruncateStmt)) { - ListCell *cell; + ListCell *cell; - TruncateStmt *stmt = (TruncateStmt *)node; + TruncateStmt *stmt = (TruncateStmt *) node; foreach(cell, stmt->relations) { @@ -1070,7 +1100,7 @@ int pool_extract_table_oids(Node *node, int **oidsp) { oids[num_oids++] = pool_table_name_to_oid(table); ereport(DEBUG1, - (errmsg("memcache: extracting table oids: table: \"%s\" oid:%d", table, oids[num_oids-1]))); + (errmsg("memcache: extracting table oids: table: \"%s\" oid:%d", table, oids[num_oids - 1]))); } } return num_oids; @@ -1093,17 +1123,18 @@ int pool_extract_table_oids(Node *node, int **oidsp) } #define POOL_OIDBUF_SIZE 1024 -static int* oidbuf; -static int oidbufp; -static int oidbuf_size; +static int *oidbuf; +static int oidbufp; +static int oidbuf_size; /* * Add table oid to internal buffer */ -void pool_add_dml_table_oid(int oid) +void +pool_add_dml_table_oid(int oid) { - int i; - int* tmp; + int i; + int *tmp; if (oid == 0) return; @@ -1111,7 +1142,9 @@ void pool_add_dml_table_oid(int oid) if (oidbufp >= oidbuf_size) { MemoryContext oldcxt; + oidbuf_size += POOL_OIDBUF_SIZE; + /* * This need to live throughout the life of child so home it in * TopMemoryContext @@ -1125,10 +1158,10 @@ void pool_add_dml_table_oid(int oid) oidbuf = tmp; } - for (i=0;i<oidbufp;i++) + for (i = 0; i < oidbufp; i++) { if (oidbuf[i] == oid) - /* Already same oid exists */ + /* Already same oid exists */ return; } oidbuf[oidbufp++] = oid; @@ -1138,28 +1171,30 @@ void pool_add_dml_table_oid(int oid) /* * Get table oid buffer */ -static int pool_get_dml_table_oid(int **oid) +static int +pool_get_dml_table_oid(int **oid) { *oid = oidbuf; return oidbufp; } -static int pool_get_dropdb_table_oids(int **oids, int dboid) +static int +pool_get_dropdb_table_oids(int **oids, int dboid) { - int *rtn = 0; - int oids_size = 0; - int *tmp; + int *rtn = 0; + int oids_size = 0; + int *tmp; - int num_oids = 0; - DIR *dir; + int num_oids = 0; + DIR *dir; struct dirent *dp; - char path[1024]; + char path[1024]; snprintf(path, sizeof(path), "%s/%d", pool_config->memqcache_oiddir, dboid); if ((dir = opendir(path)) == NULL) { ereport(DEBUG1, - (errmsg("memcache: getting drop table oids"), + (errmsg("memcache: getting drop table oids"), errdetail("Failed to open dir: %s", path))); return 0; } @@ -1192,7 +1227,8 @@ static int pool_get_dropdb_table_oids(int **oids, int dboid) } /* Discard oid internal buffer */ -static void pool_discard_dml_table_oid(void) +static void +pool_discard_dml_table_oid(void) { oidbufp = 0; } @@ -1221,13 +1257,14 @@ static void pool_discard_dml_table_oid(void) /* * Get oid of current database */ -static int pool_get_database_oid(void) +static int +pool_get_database_oid(void) { /* * Query to convert table name to oid */ - int oid = 0; - static POOL_RELCACHE *relcache; + int oid = 0; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; backend = pool_get_session_context(false)->backend; @@ -1243,7 +1280,7 @@ static int pool_get_database_oid(void) if (relcache == NULL) { ereport(LOG, - (errmsg("memcache: error creating relcache while getting database OID"))); + (errmsg("memcache: error creating relcache while getting database OID"))); return oid; } } @@ -1251,8 +1288,8 @@ static int pool_get_database_oid(void) /* * Search relcache. */ - oid = (int)(intptr_t)pool_search_relcache(relcache, backend, - MASTER_CONNECTION(backend)->sp->database); + oid = (int) (intptr_t) pool_search_relcache(relcache, backend, + MASTER_CONNECTION(backend)->sp->database); return oid; } @@ -1260,26 +1297,28 @@ static int pool_get_database_oid(void) * Get oid of current database for discarding cache files * after executing DROP DATABASE */ -int pool_get_database_oid_from_dbname(char *dbname) +int +pool_get_database_oid_from_dbname(char *dbname) { - int dboid = 0; + int dboid = 0; POOL_SELECT_RESULT *res; - char query[1024]; + char query[1024]; POOL_CONNECTION_POOL *backend; + backend = pool_get_session_context(false)->backend; - snprintf(query, sizeof(query), DATABASE_TO_OID_QUERY, dbname); + snprintf(query, sizeof(query), DATABASE_TO_OID_QUERY, dbname); do_query(MASTER(backend), query, &res, MAJOR(backend)); if (res->numrows != 1) { ereport(DEBUG1, - (errmsg("memcache: getting oid of current database"), + (errmsg("memcache: getting oid of current database"), errdetail("received %d rows", res->numrows))); free_select_result(res); return 0; - } + } dboid = atol(res->data[0]); free_select_result(res); @@ -1295,25 +1334,26 @@ int pool_get_database_oid_from_dbname(char *dbname) * As of pgpool-II 3.2, pool_handle_query_cache is responsible for that. * (pool_handle_query_cache -> pool_commit_cache -> pool_add_table_oid_map) */ -static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, int *table_oids) +static void +pool_add_table_oid_map(POOL_CACHEKEY * cachekey, int num_table_oids, int *table_oids) { - char *dir; - int dboid; - char path[1024]; - int i; - int len; + char *dir; + int dboid; + char path[1024]; + int i; + int len; /* * Create memqcache_oiddir */ dir = pool_config->memqcache_oiddir; - if (mkdir(dir, S_IREAD|S_IWRITE|S_IEXEC) == -1) + if (mkdir(dir, S_IREAD | S_IWRITE | S_IEXEC) == -1) { if (errno != EEXIST) { ereport(WARNING, - (errmsg("memcache: adding table oid maps, failed to create directory:\"%s\". error:\"%s\"", dir, strerror(errno)))); + (errmsg("memcache: adding table oid maps, failed to create directory:\"%s\". error:\"%s\"", dir, strerror(errno)))); return; } } @@ -1323,7 +1363,7 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, */ dboid = pool_get_database_oid(); ereport(DEBUG1, - (errmsg("memcache: adding table oid maps"), + (errmsg("memcache: adding table oid maps"), errdetail("dboid %d", dboid))); if (dboid <= 0) @@ -1334,7 +1374,7 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, } snprintf(path, sizeof(path), "%s/%d", dir, dboid); - if (mkdir(path, S_IREAD|S_IWRITE|S_IEXEC) == -1) + if (mkdir(path, S_IREAD | S_IWRITE | S_IEXEC) == -1) { if (errno != EEXIST) { @@ -1353,28 +1393,28 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, len = sizeof(cachekey->hashkey); } - for (i=0;i<num_table_oids;i++) + for (i = 0; i < num_table_oids; i++) { - int fd; - int oid = table_oids[i]; - int sts; + int fd; + int oid = table_oids[i]; + int sts; struct flock fl; /* * Create or open each memqcache_oiddir/database_oid/table_oid */ snprintf(path, sizeof(path), "%s/%d/%d", dir, dboid, oid); - if ((fd = open(path, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) == -1) + if ((fd = open(path, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) == -1) { ereport(WARNING, (errmsg("memcache: adding table oid maps, failed to open file:\"%s\". error:\"%s\"", path, strerror(errno)))); return; } - fl.l_type = F_WRLCK; + fl.l_type = F_WRLCK; fl.l_whence = SEEK_SET; - fl.l_start = 0; /* Offset from l_whence */ - fl.l_len = 0; /* length, 0 = to EOF */ + fl.l_start = 0; /* Offset from l_whence */ + fl.l_len = 0; /* length, 0 = to EOF */ sts = fcntl(fd, F_SETLKW, &fl); if (sts == -1) @@ -1387,15 +1427,15 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, } /* - * Below was ifdef-out because of a performance reason. - * Looking for duplicate cache entries in a file needed - * unacceptably high cost. So we gave up this and decided not - * to care about duplicate entries in the file. + * Below was ifdef-out because of a performance reason. Looking for + * duplicate cache entries in a file needed unacceptably high cost. So + * we gave up this and decided not to care about duplicate entries in + * the file. */ #ifdef NOT_USED for (;;) { - sts = read(fd, (char *)&buf, len); + sts = read(fd, (char *) &buf, len); if (sts == -1) { ereport(WARNING, @@ -1413,13 +1453,14 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, } continue; } + /* * Must be EOF */ if (sts != 0) { ereport(WARNING, - (errmsg("memcache: adding table oid maps, invalid data length:%d in file:\"%s\". error:\"%s\"",sts, path))); + (errmsg("memcache: adding table oid maps, invalid data length:%d in file:\"%s\". error:\"%s\"", sts, path))); close(fd); return; } @@ -1438,7 +1479,7 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, /* * Write cache_id or cache key at the end of file */ - sts = write(fd, (char *)cachekey, len); + sts = write(fd, (char *) cachekey, len); if (sts == -1 || sts != len) { ereport(WARNING, @@ -1454,23 +1495,25 @@ static void pool_add_table_oid_map(POOL_CACHEKEY *cachekey, int num_table_oids, * Discard all oid maps at pgpool-II startup. * This is necessary for shmem case. */ -void pool_discard_oid_maps(void) +void +pool_discard_oid_maps(void) { - char command[1024]; + char command[1024]; snprintf(command, sizeof(command), "/bin/rm -fr %s/[0-9]*", pool_config->memqcache_oiddir); - if(system(command) == -1) - ereport(WARNING, - (errmsg("unable to execute command \"%s\"",command), - errdetail("system() command failed with error \"%s\"",strerror(errno)))); - + if (system(command) == -1) + ereport(WARNING, + (errmsg("unable to execute command \"%s\"", command), + errdetail("system() command failed with error \"%s\"", strerror(errno)))); + } -void pool_discard_oid_maps_by_db(int dboid) +void +pool_discard_oid_maps_by_db(int dboid) { - char command[1024]; + char command[1024]; if (pool_is_shmem_cache()) { @@ -1481,10 +1524,10 @@ void pool_discard_oid_maps_by_db(int dboid) (errmsg("memcache: discarding oid maps by db"), errdetail("command: '%s\'", command))); - if(system(command) == -1) - ereport(WARNING, - (errmsg("unable to execute command \"%s\"",command), - errdetail("system() command failed with error \"%s\"",strerror(errno)))); + if (system(command) == -1) + ereport(WARNING, + (errmsg("unable to execute command \"%s\"", command), + errdetail("system() command failed with error \"%s\"", strerror(errno)))); } } @@ -1494,19 +1537,20 @@ void pool_discard_oid_maps_by_db(int dboid) * unlink is true, the file will be unlinked after successful cache * removal. */ -static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, int dboid) +static void +pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool unlinkp, int dboid) { - char *dir; - char path[1024]; - int i; - int len; + char *dir; + char path[1024]; + int i; + int len; POOL_CACHEKEY buf; /* * Create memqcache_oiddir */ dir = pool_config->memqcache_oiddir; - if (mkdir(dir, S_IREAD|S_IWRITE|S_IEXEC) == -1) + if (mkdir(dir, S_IREAD | S_IWRITE | S_IEXEC) == -1) { if (errno != EEXIST) { @@ -1523,7 +1567,7 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool { dboid = pool_get_database_oid(); ereport(DEBUG1, - (errmsg("memcache invalidating query cache"), + (errmsg("memcache invalidating query cache"), errdetail("dboid %d", dboid))); if (dboid <= 0) @@ -1535,7 +1579,7 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool } snprintf(path, sizeof(path), "%s/%d", dir, dboid); - if (mkdir(path, S_IREAD|S_IWRITE|S_IEXEC) == -1) + if (mkdir(path, S_IREAD | S_IWRITE | S_IEXEC) == -1) { if (errno != EEXIST) { @@ -1554,11 +1598,11 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool len = sizeof(buf.hashkey); } - for (i=0;i<num_table_oids;i++) + for (i = 0; i < num_table_oids; i++) { - int fd; - int oid = table_oid[i]; - int sts; + int fd; + int oid = table_oid[i]; + int sts; struct flock fl; /* @@ -1567,20 +1611,21 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool snprintf(path, sizeof(path), "%s/%d/%d", dir, dboid, oid); if ((fd = open(path, O_RDONLY)) == -1) { - /* This may be normal. It is possible that no SELECT has - * been issued since the table has been created or since - * pgpool-II started up. + /* + * This may be normal. It is possible that no SELECT has been + * issued since the table has been created or since pgpool-II + * started up. */ ereport(DEBUG1, - (errmsg("memcache invalidating query cache"), - errdetail("failed to open \"%s\". reason:\"%s\"",path, strerror(errno)))); + (errmsg("memcache invalidating query cache"), + errdetail("failed to open \"%s\". reason:\"%s\"", path, strerror(errno)))); continue; } - fl.l_type = F_RDLCK; + fl.l_type = F_RDLCK; fl.l_whence = SEEK_SET; - fl.l_start = 0; /* Offset from l_whence */ - fl.l_len = 0; /* length, 0 = to EOF */ + fl.l_start = 0; /* Offset from l_whence */ + fl.l_len = 0; /* length, 0 = to EOF */ sts = fcntl(fd, F_SETLKW, &fl); if (sts == -1) @@ -1592,7 +1637,7 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool } for (;;) { - sts = read(fd, (char *)&buf, len); + sts = read(fd, (char *) &buf, len); if (sts == -1) { ereport(WARNING, @@ -1606,20 +1651,20 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool if (pool_is_shmem_cache()) { ereport(DEBUG1, - (errmsg("memcache invalidating query cache"), - errdetail("deleting cacheid:%d itemid:%d", - buf.cacheid.blockid, buf.cacheid.itemid))); + (errmsg("memcache invalidating query cache"), + errdetail("deleting cacheid:%d itemid:%d", + buf.cacheid.blockid, buf.cacheid.itemid))); pool_delete_item_shmem_cache(&buf.cacheid); } #ifdef USE_MEMCACHED else { - char delbuf[33]; + char delbuf[33]; memcpy(delbuf, buf.hashkey, 32); delbuf[32] = 0; ereport(DEBUG1, - (errmsg("memcache invalidating query cache"), + (errmsg("memcache invalidating query cache"), errdetail("deleting %s", delbuf))); delete_cache_on_memcached(delbuf); @@ -1634,7 +1679,7 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool if (sts != 0) { ereport(WARNING, - (errmsg("memcache: invalidating query cache, invalid data length:%d in file:\"%s\"",sts, path))); + (errmsg("memcache: invalidating query cache, invalid data length:%d in file:\"%s\"", sts, path))); close(fd); return; } @@ -1655,9 +1700,10 @@ static void pool_invalidate_query_cache(int num_table_oids, int *table_oid, bool /* * Reset SELECT data buffers */ -static void pool_reset_memqcache_buffer(void) +static void +pool_reset_memqcache_buffer(void) { - POOL_SESSION_CONTEXT * session_context; + POOL_SESSION_CONTEXT *session_context; session_context = pool_get_session_context(true); @@ -1666,15 +1712,16 @@ static void pool_reset_memqcache_buffer(void) POOL_TEMP_QUERY_CACHE *cache; ereport(DEBUG1, - (errmsg("memcache reset buffer"), + (errmsg("memcache reset buffer"), errdetail("discard: %p", session_context->query_cache_array))); pool_discard_query_cache_array(session_context->query_cache_array); session_context->query_cache_array = pool_create_query_cache_array(); ereport(DEBUG1, - (errmsg("memcache reset buffer"), + (errmsg("memcache reset buffer"), errdetail("create: %p", session_context->query_cache_array))); + /* * if the query context is still under use, we cannot discard * temporary cache. @@ -1682,15 +1729,16 @@ static void pool_reset_memqcache_buffer(void) if (can_query_context_destroy(session_context->query_context)) { ereport(DEBUG1, - (errmsg("memcache reset buffer"), - errdetail("discard temp buffer of %p (%s)", - session_context->query_context, session_context->query_context->original_query))); + (errmsg("memcache reset buffer"), + errdetail("discard temp buffer of %p (%s)", + session_context->query_context, session_context->query_context->original_query))); cache = pool_get_current_cache(); pool_discard_temp_query_cache(cache); + /* - * Reset temp_cache pointer in the current query context - * so that we don't double free memory. + * Reset temp_cache pointer in the current query context so that + * we don't double free memory. */ session_context->query_context->temp_cache = NULL; } @@ -1703,16 +1751,18 @@ static void pool_reset_memqcache_buffer(void) * Return true if memory cache method is "shmem". The purpose of this * function is to cache the result of stcmp and to save a few cycle. */ -bool pool_is_shmem_cache(void) +bool +pool_is_shmem_cache(void) { - return (pool_config->memqcache_method == SHMEM_CACHE)?true:false; + return (pool_config->memqcache_method == SHMEM_CACHE) ? true : false; } /* * Remember memory cache number of blocks. */ -static int memqcache_num_blocks; -static void pool_set_memqcache_blocks(int num_blocks) +static int memqcache_num_blocks; +static void +pool_set_memqcache_blocks(int num_blocks) { memqcache_num_blocks = num_blocks; } @@ -1720,7 +1770,8 @@ static void pool_set_memqcache_blocks(int num_blocks) /* * Return memory cache number of blocks. */ -static int pool_get_memqcache_blocks(void) +static int +pool_get_memqcache_blocks(void) { return memqcache_num_blocks; } @@ -1732,31 +1783,32 @@ static int pool_get_memqcache_blocks(void) /* * Calculate necessary shared memory size. */ -size_t pool_shared_memory_cache_size(void) +size_t +pool_shared_memory_cache_size(void) { - int64 num_blocks; - size_t size; + int64 num_blocks; + size_t size; if (pool_config->memqcache_maxcache > pool_config->memqcache_cache_block_size) ereport(FATAL, - (errmsg("invalid memory cache configuration"), - errdetail("memqcache_cache_block_size %d should be greater or equal to memqcache_maxcache %d", - pool_config->memqcache_cache_block_size, - pool_config->memqcache_maxcache))); + (errmsg("invalid memory cache configuration"), + errdetail("memqcache_cache_block_size %d should be greater or equal to memqcache_maxcache %d", + pool_config->memqcache_cache_block_size, + pool_config->memqcache_maxcache))); - num_blocks = pool_config->memqcache_total_size/ + num_blocks = pool_config->memqcache_total_size / pool_config->memqcache_cache_block_size; if (num_blocks == 0) ereport(FATAL, - (errmsg("invalid memory cache configuration"), - errdetail("memqcache_total_size %ld should be greater or equal to memqcache_cache_block_size %d", - pool_config->memqcache_total_size, - pool_config->memqcache_cache_block_size))); + (errmsg("invalid memory cache configuration"), + errdetail("memqcache_total_size %ld should be greater or equal to memqcache_cache_block_size %d", + pool_config->memqcache_total_size, + pool_config->memqcache_cache_block_size))); - ereport(LOG, + ereport(LOG, (errmsg("memory cache initialized"), - errdetail("memcache blocks :%ld",num_blocks))); + errdetail("memcache blocks :%ld", num_blocks))); /* Remember # of blocks */ pool_set_memqcache_blocks(num_blocks); size = pool_config->memqcache_cache_block_size * num_blocks; @@ -1768,10 +1820,11 @@ size_t pool_shared_memory_cache_size(void) * only once from pgpool main process at the process staring up time. */ static void *shmem; -int pool_init_memory_cache(size_t size) +int +pool_init_memory_cache(size_t size) { ereport(DEBUG1, - (errmsg("memory cache request size : %zd",size))); + (errmsg("memory cache request size : %zd", size))); shmem = pool_shared_memory_create(size); return 0; @@ -1783,31 +1836,31 @@ int pool_init_memory_cache(size_t size) void pool_clear_memory_cache(void) { - size_t size; + size_t size; pool_sigset_t oldmask; POOL_SETMASK2(&BlockSig, &oldmask); pool_shmem_lock(); - PG_TRY(); - { - size = pool_shared_memory_cache_size(); - memset(shmem, 0, size); + PG_TRY(); + { + size = pool_shared_memory_cache_size(); + memset(shmem, 0, size); - size = pool_shared_memory_fsmm_size(); - pool_reset_fsmm(size); + size = pool_shared_memory_fsmm_size(); + pool_reset_fsmm(size); - pool_discard_oid_maps(); + pool_discard_oid_maps(); - pool_hash_reset(pool_config->memqcache_max_num_cache); - } - PG_CATCH(); - { - pool_shmem_unlock(); - POOL_SETMASK(&oldmask); - PG_RE_THROW(); - } - PG_END_TRY(); + pool_hash_reset(pool_config->memqcache_max_num_cache); + } + PG_CATCH(); + { + pool_shmem_unlock(); + POOL_SETMASK(&oldmask); + PG_RE_THROW(); + } + PG_END_TRY(); pool_shmem_unlock(); POOL_SETMASK(&oldmask); @@ -1816,7 +1869,8 @@ pool_clear_memory_cache(void) /* * Return shared memory cache address */ -static void *pool_memory_cache_address(void) +static void * +pool_memory_cache_address(void) { return shmem; } @@ -1827,7 +1881,7 @@ static void *pool_memory_cache_address(void) /* * Free space management map - * + * * Free space management map (FSMM) consists of bytes. Each byte * corresponds to block id. For example, if you have 1GB cache and * block size is 8Kb, number of blocks = 131,072, thus total size of @@ -1846,12 +1900,13 @@ static void *pool_memory_cache_address(void) */ /* - * Calculate necessary shared memory size for FSMM. Should be called after + * Calculate necessary shared memory size for FSMM. Should be called after * pool_shared_memory_cache_size. */ -size_t pool_shared_memory_fsmm_size(void) +size_t +pool_shared_memory_fsmm_size(void) { - size_t size; + size_t size; size = pool_get_memqcache_blocks() * sizeof(char); return size; @@ -1863,13 +1918,14 @@ size_t pool_shared_memory_fsmm_size(void) * main process at the process staring up time. */ static void *fsmm; -int pool_init_fsmm(size_t size) +int +pool_init_fsmm(size_t size) { - int maxblock = pool_get_memqcache_blocks(); - int encode_value; + int maxblock = pool_get_memqcache_blocks(); + int encode_value; fsmm = pool_shared_memory_create(size); - encode_value = POOL_MAX_FREE_SPACE/POOL_FSMM_RATIO; + encode_value = POOL_MAX_FREE_SPACE / POOL_FSMM_RATIO; memset(fsmm, encode_value, maxblock); return 0; } @@ -1877,7 +1933,8 @@ int pool_init_fsmm(size_t size) /* * Return shared memory fsmm address */ -static void *pool_fsmm_address(void) +static void * +pool_fsmm_address(void) { return fsmm; } @@ -1894,7 +1951,8 @@ static int *pool_fsmm_clock_hand; /* * Allocate and initialize clock hand on shmem */ -void pool_allocate_fsmm_clock_hand(void) +void +pool_allocate_fsmm_clock_hand(void) { pool_fsmm_clock_hand = pool_shared_memory_create(sizeof(*pool_fsmm_clock_hand)); *pool_fsmm_clock_hand = 0; @@ -1906,9 +1964,9 @@ void pool_allocate_fsmm_clock_hand(void) static void pool_reset_fsmm(size_t size) { - int encode_value; + int encode_value; - encode_value = POOL_MAX_FREE_SPACE/POOL_FSMM_RATIO; + encode_value = POOL_MAX_FREE_SPACE / POOL_FSMM_RATIO; memset(fsmm, encode_value, size); *pool_fsmm_clock_hand = 0; @@ -1920,19 +1978,19 @@ pool_reset_fsmm(size_t size) */ static POOL_CACHE_BLOCKID pool_reuse_block(void) { - int maxblock = pool_get_memqcache_blocks(); - char *block = block_address(*pool_fsmm_clock_hand); - POOL_CACHE_BLOCK_HEADER *bh = (POOL_CACHE_BLOCK_HEADER *)block; + int maxblock = pool_get_memqcache_blocks(); + char *block = block_address(*pool_fsmm_clock_hand); + POOL_CACHE_BLOCK_HEADER *bh = (POOL_CACHE_BLOCK_HEADER *) block; POOL_CACHE_BLOCKID reused_block; POOL_CACHE_ITEM_POINTER *cip; - char *p; - int i; + char *p; + int i; bh->flags = 0; reused_block = *pool_fsmm_clock_hand; p = block_address(reused_block); - for (i=0;i<bh->num_items;i++) + for (i = 0; i < bh->num_items; i++) { cip = item_pointer(p, i); @@ -1962,10 +2020,10 @@ static POOL_CACHE_BLOCKID pool_reuse_block(void) */ static POOL_CACHE_BLOCKID pool_get_block(size_t free_space) { - int encode_value; + int encode_value; unsigned char *p = pool_fsmm_address(); - int i; - int maxblock = pool_get_memqcache_blocks(); + int i; + int maxblock = pool_get_memqcache_blocks(); POOL_CACHE_BLOCK_HEADER *bh; if (p == NULL) @@ -1978,25 +2036,25 @@ static POOL_CACHE_BLOCKID pool_get_block(size_t free_space) if (free_space > POOL_MAX_FREE_SPACE) { ereport(WARNING, - (errmsg("memcache: getting block: invalid free space:%zd", free_space), - errdetail("requested free space: %zd is more than maximum allowed space:%lu",free_space,POOL_MAX_FREE_SPACE))); + (errmsg("memcache: getting block: invalid free space:%zd", free_space), + errdetail("requested free space: %zd is more than maximum allowed space:%lu", free_space, POOL_MAX_FREE_SPACE))); return -1; } - encode_value = free_space/POOL_FSMM_RATIO; + encode_value = free_space / POOL_FSMM_RATIO; - for (i=0;i<maxblock;i++) + for (i = 0; i < maxblock; i++) { if (p[i] >= encode_value) { /* - * This block *may" have enough space. - * We need to make sure it actually has enough space. + * This block *may" have enough space. We need to make sure it + * actually has enough space. */ - bh = (POOL_CACHE_BLOCK_HEADER *)block_address(i); + bh = (POOL_CACHE_BLOCK_HEADER *) block_address(i); if (bh->free_bytes >= free_space) { - return (POOL_CACHE_BLOCKID)i; + return (POOL_CACHE_BLOCKID) i; } } } @@ -2010,10 +2068,11 @@ static POOL_CACHE_BLOCKID pool_get_block(size_t free_space) /* * Update free space info for specified block */ -static void pool_update_fsmm(POOL_CACHE_BLOCKID blockid, size_t free_space) +static void +pool_update_fsmm(POOL_CACHE_BLOCKID blockid, size_t free_space) { - int encode_value; - char *p = pool_fsmm_address(); + int encode_value; + char *p = pool_fsmm_address(); if (p == NULL) { @@ -2025,20 +2084,20 @@ static void pool_update_fsmm(POOL_CACHE_BLOCKID blockid, size_t free_space) if (blockid >= pool_get_memqcache_blocks()) { ereport(WARNING, - (errmsg("memcache: updating free space in block: block id:%d in invalid",blockid))); + (errmsg("memcache: updating free space in block: block id:%d in invalid", blockid))); return; } if (free_space > POOL_MAX_FREE_SPACE) { ereport(WARNING, - (errmsg("memcache: updating free space in block: invalid free space:%zd", free_space), - errdetail("requested free space: %zd is more than maximum allowed space:%lu",free_space,POOL_MAX_FREE_SPACE))); + (errmsg("memcache: updating free space in block: invalid free space:%zd", free_space), + errdetail("requested free space: %zd is more than maximum allowed space:%lu", free_space, POOL_MAX_FREE_SPACE))); return; } - encode_value = free_space/POOL_FSMM_RATIO; + encode_value = free_space / POOL_FSMM_RATIO; p[blockid] = encode_value; @@ -2051,7 +2110,7 @@ static void pool_update_fsmm(POOL_CACHE_BLOCKID blockid, size_t free_space) * The cache id is overwritten by the subsequent call to this function. * On error returns NULL. */ -static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char *data, int size) +static POOL_CACHEID * pool_add_item_shmem_cache(POOL_QUERY_HASH * query_hash, char *data, int size) { static POOL_CACHEID cacheid; POOL_CACHE_BLOCKID blockid; @@ -2060,19 +2119,19 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char POOL_CACHE_ITEM ci; POOL_CACHE_ITEM_POINTER cip_body; - char *item; - - int request_size; - char *p; - int i; - char *src; - char *dst; - int num_deleted; - char *dcip; - char *dci; - bool need_pack; - char *work_buffer; - int index; + char *item; + + int request_size; + char *p; + int i; + char *src; + char *dst; + int num_deleted; + char *dcip; + char *dci; + bool need_pack; + char *work_buffer; + int index; if (query_hash == NULL) { @@ -2107,9 +2166,9 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char } /* - * Initialize the block if necessary. If no live items are - * remained, we also initialize the block. If there's contiguous - * deleted items, we turn them into free space as well. + * Initialize the block if necessary. If no live items are remained, we + * also initialize the block. If there's contiguous deleted items, we turn + * them into free space as well. */ pool_init_cache_block(blockid); @@ -2125,37 +2184,36 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char /* Get block address on shmem */ p = block_address(blockid); - bh = (POOL_CACHE_BLOCK_HEADER *)p; + bh = (POOL_CACHE_BLOCK_HEADER *) p; /* - * Create contiguous free space. We assume that item bodies are - * ordered from bottom to top of the block, and corresponding item - * pointers are ordered from the youngest to the oldest in the - * beginning of the block. + * Create contiguous free space. We assume that item bodies are ordered + * from bottom to top of the block, and corresponding item pointers are + * ordered from the youngest to the oldest in the beginning of the block. */ /* - * Optimization. If there's no deleted items, we don't need to - * pack it to create contiguous free space. + * Optimization. If there's no deleted items, we don't need to pack it to + * create contiguous free space. */ need_pack = false; - for (i=0;i<bh->num_items;i++) + for (i = 0; i < bh->num_items; i++) { cip = item_pointer(p, i); - if (POOL_ITEM_DELETED & cip->flags) /* Deleted item? */ + if (POOL_ITEM_DELETED & cip->flags) /* Deleted item? */ { need_pack = true; ereport(DEBUG1, - (errmsg("memcache adding item"), + (errmsg("memcache adding item"), errdetail("start creating contiguous space"))); break; } } /* - * We disable packing for now. - * Revisit and remove following code fragment later. + * We disable packing for now. Revisit and remove following code fragment + * later. */ need_pack = false; @@ -2177,14 +2235,14 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char num_deleted = 0; index = 0; - for (i=0;i<bh->num_items;i++) + for (i = 0; i < bh->num_items; i++) { - int total_length; + int total_length; POOL_CACHEID cid; cip = item_pointer(p, i); - if (POOL_ITEM_DELETED & cip->flags) /* Deleted item? */ + if (POOL_ITEM_DELETED & cip->flags) /* Deleted item? */ { num_deleted++; continue; @@ -2200,8 +2258,8 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char dci -= total_length; /* Copy item pointer */ - src = (char *)cip; - dst = (char *)item_pointer(dcip, index); + src = (char *) cip; + dst = (char *) item_pointer(dcip, index); memcpy(dst, src, sizeof(POOL_CACHE_ITEM_POINTER)); /* Update hash index */ @@ -2209,17 +2267,17 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char cid.itemid = index; pool_hash_insert(&cip->query_hash, &cid, true); ereport(DEBUG1, - (errmsg("memcache adding item"), - errdetail("item cid updated. old:%d %d new:%d %d", - blockid, i, blockid, index))); + (errmsg("memcache adding item"), + errdetail("item cid updated. old:%d %d new:%d %d", + blockid, i, blockid, index))); index++; } - + /* All items deleted? */ if (num_deleted > 0 && num_deleted == bh->num_items) { ereport(DEBUG1, - (errmsg("memcache adding item"), + (errmsg("memcache adding item"), errdetail("all items deleted, total deleted:%d", num_deleted))); bh->flags = 0; pool_init_cache_block(blockid); @@ -2231,9 +2289,9 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char bh->num_items -= num_deleted; /* Copy back the packed block except block header */ - memcpy(p+sizeof(POOL_CACHE_BLOCK_HEADER), - work_buffer+sizeof(POOL_CACHE_BLOCK_HEADER), - pool_config->memqcache_cache_block_size-sizeof(POOL_CACHE_BLOCK_HEADER)); + memcpy(p + sizeof(POOL_CACHE_BLOCK_HEADER), + work_buffer + sizeof(POOL_CACHE_BLOCK_HEADER), + pool_config->memqcache_cache_block_size - sizeof(POOL_CACHE_BLOCK_HEADER)); } free(work_buffer); } @@ -2245,7 +2303,7 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char { /* This should not happen */ ereport(WARNING, - (errmsg("memcache: adding item to cache: not enough space"), + (errmsg("memcache: adding item to cache: not enough space"), errdetail("free space: %d required: %d block id:%d", bh->free_bytes, request_size, blockid))); return NULL; @@ -2262,8 +2320,9 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char /* Calculate item body address */ if (bh->num_items == 0) { - /* This is the #0 item. So address is block_bottom - - * data_length */ + /* + * This is the #0 item. So address is block_bottom - data_length + */ item = p + pool_config->memqcache_cache_block_size - ci.header.total_length; /* Mark this block used */ @@ -2271,7 +2330,7 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char } else { - cip = item_pointer(p, bh->num_items-1); + cip = item_pointer(p, bh->num_items - 1); item = p + cip->offset - ci.header.total_length; } @@ -2297,9 +2356,9 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char cacheid.blockid = blockid; cacheid.itemid = bh->num_items; ereport(DEBUG1, - (errmsg("memcache adding item"), - errdetail("new item inserted. blockid: %d itemid:%d", - cacheid.blockid, cacheid.itemid))); + (errmsg("memcache adding item"), + errdetail("new item inserted. blockid: %d itemid:%d", + cacheid.blockid, cacheid.itemid))); /* Add up number of items */ bh->num_items++; @@ -2310,14 +2369,15 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char ereport(LOG, (errmsg("error while adding item to shmem cache, hash insert failed"))); - /* Since we have failed to insert hash index entry, we need to - * undo the addition of cache entry. + /* + * Since we have failed to insert hash index entry, we need to undo + * the addition of cache entry. */ pool_delete_item_shmem_cache(&cacheid); return NULL; } ereport(DEBUG1, - (errmsg("memcache adding item"), + (errmsg("memcache adding item"), errdetail("block: %d item: %d", cacheid.blockid, cacheid.itemid))); #ifdef SHMEMCACHE_DEBUG @@ -2332,7 +2392,8 @@ static POOL_CACHEID *pool_add_item_shmem_cache(POOL_QUERY_HASH *query_hash, char * On error or data not found case returns NULL. * Detail is set to *sts. (0: success, 1: not found, -1: error) */ -static char *pool_get_item_shmem_cache(POOL_QUERY_HASH *query_hash, int *size, int *sts) +static char * +pool_get_item_shmem_cache(POOL_QUERY_HASH * query_hash, int *size, int *sts) { POOL_CACHEID *cacheid; POOL_CACHE_ITEM_HEADER *cih; @@ -2374,7 +2435,7 @@ static char *pool_get_item_shmem_cache(POOL_QUERY_HASH *query_hash, int *size, i cih = pool_cache_item_header(cacheid); *size = cih->total_length - sizeof(POOL_CACHE_ITEM_HEADER); - return (char *)cih + sizeof(POOL_CACHE_ITEM_HEADER); + return (char *) cih + sizeof(POOL_CACHE_ITEM_HEADER); } /* @@ -2382,12 +2443,12 @@ static char *pool_get_item_shmem_cache(POOL_QUERY_HASH *query_hash, int *size, i * On success returns cache id. * The cache id is overwritten by the subsequent call to this function. */ -static POOL_CACHEID *pool_find_item_on_shmem_cache(POOL_QUERY_HASH *query_hash) +static POOL_CACHEID * pool_find_item_on_shmem_cache(POOL_QUERY_HASH * query_hash) { static POOL_CACHEID cacheid; POOL_CACHEID *c; POOL_CACHE_ITEM_HEADER *cih; - time_t now; + time_t now; c = pool_hash_search(query_hash); if (!c) @@ -2404,9 +2465,9 @@ static POOL_CACHEID *pool_find_item_on_shmem_cache(POOL_QUERY_HASH *query_hash) if (now > (cih->timestamp + pool_config->memqcache_expire)) { ereport(DEBUG1, - (errmsg("memcache finding item"), - errdetail("cache expired: now: %ld timestamp: %ld", - now, cih->timestamp + pool_config->memqcache_expire))); + (errmsg("memcache finding item"), + errdetail("cache expired: now: %ld timestamp: %ld", + now, cih->timestamp + pool_config->memqcache_expire))); pool_delete_item_shmem_cache(c); return NULL; } @@ -2423,16 +2484,18 @@ static POOL_CACHEID *pool_find_item_on_shmem_cache(POOL_QUERY_HASH *query_hash) * Other wise return -1. * FSMM is also updated. */ -static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid) +static int +pool_delete_item_shmem_cache(POOL_CACHEID * cacheid) { POOL_CACHE_BLOCK_HEADER *bh; POOL_CACHE_ITEM_POINTER *cip; POOL_CACHE_ITEM_HEADER *cih; POOL_QUERY_HASH key; - int size; + int size; + ereport(DEBUG1, - (errmsg("memcache deleting item data"), - errdetail("cacheid:%d itemid:%d",cacheid->blockid, cacheid->itemid))); + (errmsg("memcache deleting item data"), + errdetail("cacheid:%d itemid:%d", cacheid->blockid, cacheid->itemid))); if (cacheid->blockid >= pool_get_memqcache_blocks()) { @@ -2442,7 +2505,7 @@ static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid) return -1; } - bh = (POOL_CACHE_BLOCK_HEADER *)block_address(cacheid->blockid); + bh = (POOL_CACHE_BLOCK_HEADER *) block_address(cacheid->blockid); if (!(bh->flags & POOL_BLOCK_USED)) { ereport(LOG, @@ -2454,13 +2517,13 @@ static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid) if (cacheid->itemid >= bh->num_items) { /* - * This could happen if the block is reused. Since contents - * of oid map file is not updated when the block is reused. + * This could happen if the block is reused. Since contents of oid + * map file is not updated when the block is reused. */ ereport(DEBUG1, - (errmsg("memcache error deleting item data"), - errdetail("invalid item id %d in block:%d", - cacheid->itemid, cacheid->blockid))); + (errmsg("memcache error deleting item data"), + errdetail("invalid item id %d in block:%d", + cacheid->itemid, cacheid->blockid))); return -1; } @@ -2492,18 +2555,17 @@ static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid) cip->flags |= POOL_ITEM_DELETED; /* - * We do NOT count down bh->num_items here. The deleted space will be recycled - * by pool_add_item_shmem_cache(). However, if this is the last item, we can - * recycle whole block. + * We do NOT count down bh->num_items here. The deleted space will be + * recycled by pool_add_item_shmem_cache(). However, if this is the last + * item, we can recycle whole block. * - * 2012/4/1: Now we do not pack data in - * pool_add_item_shmem_cache() for performance reason. Also we - * count down num_items if it is the last one. + * 2012/4/1: Now we do not pack data in pool_add_item_shmem_cache() for + * performance reason. Also we count down num_items if it is the last one. */ - if ((bh->num_items -1) == 0) + if ((bh->num_items - 1) == 0) { ereport(DEBUG1, - (errmsg("memcache deleting item data"), + (errmsg("memcache deleting item data"), errdetail("no item remains. initialize block"))); bh->flags = 0; pool_init_cache_block(cacheid->blockid); @@ -2513,15 +2575,16 @@ static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid) pool_hash_delete(&key); /* - * If the deleted item is last one in the block, we add it to the free space. + * If the deleted item is last one in the block, we add it to the free + * space. */ - if (cacheid->itemid == (bh->num_items -1)) + if (cacheid->itemid == (bh->num_items - 1)) { bh->free_bytes += size; ereport(DEBUG1, - (errmsg("memcache deleting item data"), - errdetail("deleted %d bytes, freebytes is = %d", - size, bh->free_bytes))); + (errmsg("memcache deleting item data"), + errdetail("deleted %d bytes, freebytes is = %d", + size, bh->free_bytes))); bh->num_items--; } @@ -2535,7 +2598,7 @@ static int pool_delete_item_shmem_cache(POOL_CACHEID *cacheid) /* * Returns item header specified by cache id. */ -static POOL_CACHE_ITEM_HEADER *pool_cache_item_header(POOL_CACHEID *cacheid) +static POOL_CACHE_ITEM_HEADER * pool_cache_item_header(POOL_CACHEID * cacheid) { POOL_CACHE_BLOCK_HEADER *bh; @@ -2546,7 +2609,7 @@ static POOL_CACHE_ITEM_HEADER *pool_cache_item_header(POOL_CACHEID *cacheid) return NULL; } - bh = (POOL_CACHE_BLOCK_HEADER *)block_address(cacheid->blockid); + bh = (POOL_CACHE_BLOCK_HEADER *) block_address(cacheid->blockid); if (cacheid->itemid >= bh->num_items) { ereport(WARNING, @@ -2554,15 +2617,16 @@ static POOL_CACHE_ITEM_HEADER *pool_cache_item_header(POOL_CACHEID *cacheid) return NULL; } - return item_header((char *)bh, cacheid->itemid); + return item_header((char *) bh, cacheid->itemid); } /* * Initialize specified block. */ -static int pool_init_cache_block(POOL_CACHE_BLOCKID blockid) +static int +pool_init_cache_block(POOL_CACHE_BLOCKID blockid) { - char *p; + char *p; POOL_CACHE_BLOCK_HEADER *bh; if (blockid >= pool_get_memqcache_blocks()) @@ -2573,7 +2637,7 @@ static int pool_init_cache_block(POOL_CACHE_BLOCKID blockid) } p = block_address(blockid); - bh = (POOL_CACHE_BLOCK_HEADER *)p; + bh = (POOL_CACHE_BLOCK_HEADER *) p; /* Is this block used? */ if (!(bh->flags & POOL_BLOCK_USED)) @@ -2590,24 +2654,25 @@ static int pool_init_cache_block(POOL_CACHE_BLOCKID blockid) /* * Delete all items in the block. */ -static void pool_wipe_out_cache_block(POOL_CACHE_BLOCKID blockid) +static void +pool_wipe_out_cache_block(POOL_CACHE_BLOCKID blockid) { - char *p; + char *p; POOL_CACHE_BLOCK_HEADER *bh; POOL_CACHE_ITEM_POINTER *cip; POOL_CACHEID cacheid; - int i; + int i; /* Get block address on shmem */ p = block_address(blockid); - bh = (POOL_CACHE_BLOCK_HEADER *)p; + bh = (POOL_CACHE_BLOCK_HEADER *) p; cacheid.blockid = blockid; - for (i=0;i<bh->num_items;i++) + for (i = 0; i < bh->num_items; i++) { cip = item_pointer(p, i); - if ((POOL_ITEM_DELETED & cip->flags) == 0) /* Not deleted item? */ + if ((POOL_ITEM_DELETED & cip->flags) == 0) /* Not deleted item? */ { cacheid.itemid = i; pool_delete_item_shmem_cache(&cacheid); @@ -2623,7 +2688,8 @@ static void pool_wipe_out_cache_block(POOL_CACHE_BLOCKID blockid) /* * Acquire lock: XXX giant lock */ -void pool_shmem_lock(void) +void +pool_shmem_lock(void) { if (pool_is_shmem_cache()) { @@ -2635,7 +2701,8 @@ void pool_shmem_lock(void) /* * Release lock */ -void pool_shmem_unlock(void) +void +pool_shmem_unlock(void) { if (pool_is_shmem_cache()) { @@ -2644,57 +2711,59 @@ void pool_shmem_unlock(void) } /* - * Returns cache block address specified by block id + * Returns cache block address specified by block id */ -static char *block_address(int blockid) +static char * +block_address(int blockid) { - char *p; + char *p; p = pool_memory_cache_address() + - blockid * pool_config->memqcache_cache_block_size; + blockid * pool_config->memqcache_cache_block_size; return p; } /* * Returns i th item pointer in block address block */ -static POOL_CACHE_ITEM_POINTER *item_pointer(char *block, int i) +static POOL_CACHE_ITEM_POINTER * item_pointer(char *block, int i) { - return (POOL_CACHE_ITEM_POINTER *)(block + sizeof(POOL_CACHE_BLOCK_HEADER) + - sizeof(POOL_CACHE_ITEM_POINTER) * i); + return (POOL_CACHE_ITEM_POINTER *) (block + sizeof(POOL_CACHE_BLOCK_HEADER) + + sizeof(POOL_CACHE_ITEM_POINTER) * i); } /* * Returns i th item header in block address block */ -static POOL_CACHE_ITEM_HEADER *item_header(char *block, int i) +static POOL_CACHE_ITEM_HEADER * item_header(char *block, int i) { POOL_CACHE_ITEM_POINTER *cip; cip = item_pointer(block, i); - return (POOL_CACHE_ITEM_HEADER *)(block + cip->offset); + return (POOL_CACHE_ITEM_HEADER *) (block + cip->offset); } #ifdef SHMEMCACHE_DEBUG /* * Dump shmem cache block */ -static void dump_shmem_cache(POOL_CACHE_BLOCKID blockid) +static void +dump_shmem_cache(POOL_CACHE_BLOCKID blockid) { POOL_CACHE_BLOCK_HEADER *bh; POOL_CACHE_ITEM_POINTER *cip; POOL_CACHE_ITEM_HEADER *cih; - int i; + int i; - bh = (POOL_CACHE_BLOCK_HEADER *)block_address(blockid); + bh = (POOL_CACHE_BLOCK_HEADER *) block_address(blockid); fprintf(stderr, "shmem: block header(%lu bytes): flags:%x num_items:%d free_bytes:%d\n", sizeof(*bh), bh->flags, bh->num_items, bh->free_bytes); - for (i=0;i<bh->num_items;i++) + for (i = 0; i < bh->num_items; i++) { - cip = item_pointer((char *)bh, i); + cip = item_pointer((char *) bh, i); fprintf(stderr, "shmem: block: %d %d th item pointer(%lu bytes): offset:%d flags:%x\n", blockid, i, sizeof(*cip), cip->offset, cip->flags); - cih = item_header((char *)bh, i); + cih = item_header((char *) bh, i); fprintf(stderr, "shmem: block: %d %d th item header(%lu bytes): timestamp:%ld length:%d\n", blockid, i, sizeof(*cih), cih->timestamp, cih->total_length); } @@ -2704,14 +2773,15 @@ static void dump_shmem_cache(POOL_CACHE_BLOCKID blockid) /* * SELECT query result array modules */ -POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void) +POOL_QUERY_CACHE_ARRAY * +pool_create_query_cache_array(void) { #define POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM 128 #define POOL_QUERY_CACHE_ARRAY_HEADER_SIZE (sizeof(int)+sizeof(int)) - size_t size; + size_t size; POOL_QUERY_CACHE_ARRAY *p; - POOL_SESSION_CONTEXT *session_context =pool_get_session_context(false); + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); size = POOL_QUERY_CACHE_ARRAY_HEADER_SIZE + POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM * @@ -2719,28 +2789,29 @@ POOL_QUERY_CACHE_ARRAY *pool_create_query_cache_array(void) p = palloc(size); p->num_caches = 0; p->array_size = POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM; - MemoryContextSwitchTo(old_context); + MemoryContextSwitchTo(old_context); return p; } /* * Discard query cache array */ -void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array) +void +pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY * cache_array) { - int i; + int i; if (!cache_array) return; ereport(DEBUG1, - (errmsg("memcache discarding query cache array"), + (errmsg("memcache discarding query cache array"), errdetail("num_caches: %d", cache_array->num_caches))); - for (i=0;i<cache_array->num_caches;i++) + for (i = 0; i < cache_array->num_caches; i++) { ereport(DEBUG2, - (errmsg("memcache discarding query cache array"), + (errmsg("memcache discarding query cache array"), errdetail("cache no: %d cache: %p", i, cache_array->caches[i]))); pool_discard_temp_query_cache(cache_array->caches[i]); } @@ -2750,18 +2821,18 @@ void pool_discard_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array) /* * Add query cache array */ -static POOL_QUERY_CACHE_ARRAY * pool_add_query_cache_array(POOL_QUERY_CACHE_ARRAY *cache_array, POOL_TEMP_QUERY_CACHE *cache) +static POOL_QUERY_CACHE_ARRAY * pool_add_query_cache_array(POOL_QUERY_CACHE_ARRAY * cache_array, POOL_TEMP_QUERY_CACHE * cache) { - size_t size; + size_t size; POOL_QUERY_CACHE_ARRAY *cp = cache_array; if (!cache_array) return cp; ereport(DEBUG2, - (errmsg("memcache adding query cache array"), + (errmsg("memcache adding query cache array"), errdetail("num_caches: %d cache: %p", cache_array->num_caches, cache))); - if (cache_array->num_caches >= cache_array->array_size) + if (cache_array->num_caches >= cache_array->array_size) { cache_array->array_size += POOL_QUERY_CACHE_ARRAY_ALLOCATE_NUM; size = POOL_QUERY_CACHE_ARRAY_HEADER_SIZE + cache_array->array_size * @@ -2779,21 +2850,23 @@ static POOL_QUERY_CACHE_ARRAY * pool_add_query_cache_array(POOL_QUERY_CACHE_ARRA /* * Create SELECT result temporary cache */ -POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query) +POOL_TEMP_QUERY_CACHE * +pool_create_temp_query_cache(char *query) { - POOL_SESSION_CONTEXT *session_context =pool_get_session_context(false); - MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); + MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); POOL_TEMP_QUERY_CACHE *p; + p = palloc(sizeof(*p)); - p->query = pstrdup(query); + p->query = pstrdup(query); - p->buffer = pool_create_buffer(); - p->oids = pool_create_buffer(); - p->num_oids = 0; - p->is_exceeded = false; - p->is_discarded = false; + p->buffer = pool_create_buffer(); + p->oids = pool_create_buffer(); + p->num_oids = 0; + p->is_exceeded = false; + p->is_discarded = false; - MemoryContextSwitchTo(old_context); + MemoryContextSwitchTo(old_context); ereport(DEBUG1, (errmsg("pool_create_temp_query_cache: cache created: %p", p))); @@ -2804,7 +2877,8 @@ POOL_TEMP_QUERY_CACHE *pool_create_temp_query_cache(char *query) /* * Discard temp query cache */ -void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache) +void +pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache) { if (!temp_cache) return; @@ -2825,19 +2899,21 @@ void pool_discard_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache) * Add data to temp query cache. * Data must be FE/BE protocol packet. */ -static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char kind, char *data, int data_len) +static void +pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache, char kind, char *data, int data_len) { POOL_INTERNAL_BUFFER *buffer; - size_t buflen; - int send_len; + size_t buflen; + int send_len; if (temp_cache == NULL) { - /* This could happen if cache exceeded in previous query - * execution in the same unnamed portal. + /* + * This could happen if cache exceeded in previous query execution in + * the same unnamed portal. */ ereport(DEBUG1, - (errmsg("memcache adding temporary query cache"), + (errmsg("memcache adding temporary query cache"), errdetail("POOL_TEMP_QUERY_CACHE is NULL"))); return; } @@ -2845,7 +2921,7 @@ static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char ki if (temp_cache->is_exceeded) { ereport(DEBUG1, - (errmsg("memcache adding temporary query cache"), + (errmsg("memcache adding temporary query cache"), errdetail("memqcache_maxcache exceeds"))); return; } @@ -2854,8 +2930,8 @@ static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char ki * We only store T(Table Description), D(Data row), C(Command Complete), * 1(ParseComplete), 2(BindComplete) */ - if (kind != 'T' && kind != 'D' && kind != 'C' && kind != '1' && kind != '2') - { + if (kind != 'T' && kind != 'D' && kind != 'C' && kind != '1' && kind != '2') + { return; } @@ -2863,19 +2939,19 @@ static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char ki buffer = temp_cache->buffer; buflen = pool_get_buffer_length(buffer); - if ((buflen+data_len+sizeof(int)+1) > pool_config->memqcache_maxcache) + if ((buflen + data_len + sizeof(int) + 1) > pool_config->memqcache_maxcache) { ereport(DEBUG1, - (errmsg("memcache adding temporary query cache"), - errdetail("data size exceeds memqcache_maxcache. current:%zd requested:%zd memq_maxcache:%d", - buflen, data_len+sizeof(int)+1, pool_config->memqcache_maxcache))); + (errmsg("memcache adding temporary query cache"), + errdetail("data size exceeds memqcache_maxcache. current:%zd requested:%zd memq_maxcache:%d", + buflen, data_len + sizeof(int) + 1, pool_config->memqcache_maxcache))); temp_cache->is_exceeded = true; return; } pool_add_buffer(buffer, &kind, 1); send_len = htonl(data_len + sizeof(int)); - pool_add_buffer(buffer, (char *)&send_len, sizeof(int)); + pool_add_buffer(buffer, (char *) &send_len, sizeof(int)); pool_add_buffer(buffer, data, data_len); return; @@ -2884,7 +2960,8 @@ static void pool_add_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, char ki /* * Add table oids used by SELECT to temp query cache. */ -static void pool_add_oids_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, int num_oids, int *oids) +static void +pool_add_oids_temp_query_cache(POOL_TEMP_QUERY_CACHE * temp_cache, int num_oids, int *oids) { POOL_INTERNAL_BUFFER *buffer; @@ -2892,7 +2969,7 @@ static void pool_add_oids_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, in return; buffer = temp_cache->oids; - pool_add_buffer(buffer, oids, num_oids*sizeof(int)); + pool_add_buffer(buffer, oids, num_oids * sizeof(int)); temp_cache->num_oids = num_oids; } @@ -2911,9 +2988,10 @@ static void pool_add_oids_temp_query_cache(POOL_TEMP_QUERY_CACHE *temp_cache, in /* * Create and return internal buffer */ -static POOL_INTERNAL_BUFFER *pool_create_buffer(void) +static POOL_INTERNAL_BUFFER * pool_create_buffer(void) { POOL_INTERNAL_BUFFER *p; + p = palloc0(sizeof(*p)); return p; } @@ -2921,7 +2999,8 @@ static POOL_INTERNAL_BUFFER *pool_create_buffer(void) /* * Discard internal buffer */ -static void pool_discard_buffer(POOL_INTERNAL_BUFFER *buffer) +static void +pool_discard_buffer(POOL_INTERNAL_BUFFER * buffer) { if (buffer) { @@ -2934,34 +3013,36 @@ static void pool_discard_buffer(POOL_INTERNAL_BUFFER *buffer) /* * Add data to internal buffer */ -static void pool_add_buffer(POOL_INTERNAL_BUFFER *buffer, void *data, size_t len) +static void +pool_add_buffer(POOL_INTERNAL_BUFFER * buffer, void *data, size_t len) { #define POOL_ALLOCATE_UNIT 8192 /* Sanity check */ if (!buffer || !data || len == 0) return; - POOL_SESSION_CONTEXT *session_context =pool_get_session_context(false); + POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); MemoryContext old_context = MemoryContextSwitchTo(session_context->memory_context); /* Check if we need to increase the buffer size */ if ((buffer->buflen + len) > buffer->bufsize) { - size_t allocate_size = ((buffer->buflen + len)/POOL_ALLOCATE_UNIT +1)*POOL_ALLOCATE_UNIT; + size_t allocate_size = ((buffer->buflen + len) / POOL_ALLOCATE_UNIT + 1) * POOL_ALLOCATE_UNIT; + ereport(DEBUG2, - (errmsg("memcache adding data to internal buffer"), - errdetail("realloc old size:%zd new size:%zd", - buffer->bufsize, allocate_size))); + (errmsg("memcache adding data to internal buffer"), + errdetail("realloc old size:%zd new size:%zd", + buffer->bufsize, allocate_size))); buffer->bufsize = allocate_size; - buffer->buf = (char *)repalloc(buffer->buf, buffer->bufsize); + buffer->buf = (char *) repalloc(buffer->buf, buffer->bufsize); } /* Add data to buffer */ - memcpy(buffer->buf+buffer->buflen, data, len); + memcpy(buffer->buf + buffer->buflen, data, len); buffer->buflen += len; ereport(DEBUG2, - (errmsg("memcache adding data to internal buffer"), - errdetail("len:%zd, total:%zd bufsize:%zd", - len, buffer->buflen, buffer->bufsize))); + (errmsg("memcache adding data to internal buffer"), + errdetail("len:%zd, total:%zd bufsize:%zd", + len, buffer->buflen, buffer->bufsize))); MemoryContextSwitchTo(old_context); return; } @@ -2971,9 +3052,10 @@ static void pool_add_buffer(POOL_INTERNAL_BUFFER *buffer, void *data, size_t len * Data is stored in newly malloc memory. * Data length is returned to len. */ -static void *pool_get_buffer(POOL_INTERNAL_BUFFER *buffer, size_t *len) +static void * +pool_get_buffer(POOL_INTERNAL_BUFFER * buffer, size_t *len) { - void *p; + void *p; if (buffer->bufsize == 0 || buffer->buflen == 0 || buffer->buf == NULL) @@ -2991,7 +3073,8 @@ static void *pool_get_buffer(POOL_INTERNAL_BUFFER *buffer, size_t *len) /* * Get internal buffer length. */ -static size_t pool_get_buffer_length(POOL_INTERNAL_BUFFER *buffer) +static size_t +pool_get_buffer_length(POOL_INTERNAL_BUFFER * buffer) { if (buffer == NULL) return 0; @@ -3003,7 +3086,8 @@ static size_t pool_get_buffer_length(POOL_INTERNAL_BUFFER *buffer) /* * Get internal buffer pointer. */ -static char *pool_get_buffer_pointer(POOL_INTERNAL_BUFFER *buffer) +static char * +pool_get_buffer_pointer(POOL_INTERNAL_BUFFER * buffer) { if (buffer == NULL) return NULL; @@ -3013,7 +3097,8 @@ static char *pool_get_buffer_pointer(POOL_INTERNAL_BUFFER *buffer) /* * Get query cache buffer struct of current query context */ -POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void) +POOL_TEMP_QUERY_CACHE * +pool_get_current_cache(void) { POOL_SESSION_CONTEXT *session_context; POOL_QUERY_CONTEXT *query_context; @@ -3034,9 +3119,11 @@ POOL_TEMP_QUERY_CACHE *pool_get_current_cache(void) /* * Get query cache buffer of current query context */ -static char *pool_get_current_cache_buffer(size_t *len) +static char * +pool_get_current_cache_buffer(size_t *len) { - char *p = NULL; + char *p = NULL; + *len = 0; POOL_TEMP_QUERY_CACHE *cache; @@ -3052,14 +3139,17 @@ static char *pool_get_current_cache_buffer(size_t *len) * Mark this temporary query cache buffer discarded if the SELECT * uses the table oid specified by oids. */ -static void pool_check_and_discard_cache_buffer(int num_oids, int *oids) +static void +pool_check_and_discard_cache_buffer(int num_oids, int *oids) { POOL_SESSION_CONTEXT *session_context; POOL_TEMP_QUERY_CACHE *cache; - int num_caches; - size_t len; - int *soids; - int i, j, k; + int num_caches; + size_t len; + int *soids; + int i, + j, + k; session_context = pool_get_session_context(true); @@ -3068,27 +3158,27 @@ static void pool_check_and_discard_cache_buffer(int num_oids, int *oids) num_caches = session_context->query_cache_array->num_caches; - for (i=0;i<num_caches;i++) + for (i = 0; i < num_caches; i++) { cache = session_context->query_cache_array->caches[i]; if (!cache || cache->is_discarded) continue; - soids = (int *)pool_get_buffer(cache->oids, &len); + soids = (int *) pool_get_buffer(cache->oids, &len); if (!soids || !len) continue; - for(j=0;j<cache->num_oids;j++) + for (j = 0; j < cache->num_oids; j++) { if (cache->is_discarded) break; - for (k=0;k<num_oids;k++) + for (k = 0; k < num_oids; k++) { if (soids[j] == oids[k]) { ereport(DEBUG1, - (errmsg("discard cache for \"%s\"",cache->query))); + (errmsg("discard cache for \"%s\"", cache->query))); cache->is_discarded = true; break; } @@ -3103,15 +3193,16 @@ static void pool_check_and_discard_cache_buffer(int num_oids, int *oids) * replication mode and extended query at Comand Complete handle query cache. * For other case At Ready for Query handle query cache. */ -void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *node, char state) +void +pool_handle_query_cache(POOL_CONNECTION_POOL * backend, char *query, Node *node, char state) { POOL_SESSION_CONTEXT *session_context; pool_sigset_t oldmask; - char *cache_buffer; - size_t len; - int num_oids; - int *oids; - int i; + char *cache_buffer; + size_t len; + int num_oids; + int *oids; + int i; session_context = pool_get_session_context(true); @@ -3120,12 +3211,13 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n { SelectContext ctx; MemoryContext old_context; + old_context = MemoryContextSwitchTo(session_context->memory_context); num_oids = pool_extract_table_oids_from_select_stmt(node, &ctx); MemoryContextSwitchTo(old_context); oids = ctx.table_oids; ereport(DEBUG2, - (errmsg("query cache handler for ReadyForQuery"), + (errmsg("query cache handler for ReadyForQuery"), errdetail("num_oids: %d oid: %d", num_oids, *oids))); if (state == 'I') /* Not inside a transaction? */ @@ -3136,15 +3228,16 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n if (!pool_is_cache_exceeded()) { POOL_TEMP_QUERY_CACHE *cache; + /* - * If we are not inside a transaction, we can - * immediately register to cache storage. + * If we are not inside a transaction, we can immediately + * register to cache storage. */ /* Register to memcached or shmem */ POOL_SETMASK2(&BlockSig, &oldmask); pool_shmem_lock(); - cache_buffer = pool_get_current_cache_buffer(&len); + cache_buffer = pool_get_current_cache_buffer(&len); if (cache_buffer) { if (session_context->query_context->skip_cache_commit == false) @@ -3155,14 +3248,15 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n (errmsg("ReadyForQuery: pool_commit_cache failed"))); } } + /* - * Reset temporary query cache buffer. This is - * necessary if extended query protocol is used and a - * bind/execute message arrives which uses a statement - * created by prior parse message. In this case since - * the temp_cache is not initialized by a parse - * message, messages are added to pre existing temp - * cache buffer. The problem was found in bug#152. + * Reset temporary query cache buffer. This is necessary + * if extended query protocol is used and a bind/execute + * message arrives which uses a statement created by prior + * parse message. In this case since the temp_cache is not + * initialized by a parse message, messages are added to + * pre existing temp cache buffer. The problem was found + * in bug#152. * http://www.pgpool.net/mantisbt/view.php?id=152 */ cache = pool_get_current_cache(); @@ -3193,9 +3287,9 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n /* In transaction. Keep to temp query cache array */ pool_add_oids_temp_query_cache(cache, num_oids, oids); - /* - * If temp cache has been overflowed, just trash the half - * baked temp cache. + /* + * If temp cache has been overflowed, just trash the half baked + * temp cache. */ if (pool_is_cache_exceeded()) { @@ -3203,28 +3297,30 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n cache = pool_get_current_cache(); pool_discard_temp_query_cache(cache); + /* - * Reset temp_cache pointer in the current query context - * so that we don't double free memory. + * Reset temp_cache pointer in the current query context so + * that we don't double free memory. */ session_context->query_context->temp_cache = NULL; } + /* * Otherwise add to the temp cache array. */ else { - session_context->query_cache_array = + session_context->query_cache_array = pool_add_query_cache_array(session_context->query_cache_array, cache); + /* - * Reset temp_cache pointer in the current query - * context so that we don't add the same temp cache to - * the cache array. This is necessary such that case - * when next query is just a "bind message", without - * "parse message". In the case the query context is - * reused and same cache pointer will be added to the - * query_cache_array which we do not want. + * Reset temp_cache pointer in the current query context so + * that we don't add the same temp cache to the cache array. + * This is necessary such that case when next query is just a + * "bind message", without "parse message". In the case the + * query context is reused and same cache pointer will be + * added to the query_cache_array which we do not want. */ session_context->query_context->temp_cache = NULL; } @@ -3238,9 +3334,9 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n /* Discard buffered data */ pool_reset_memqcache_buffer(); } - else if (is_commit_query(node)) /* Commit? */ + else if (is_commit_query(node)) /* Commit? */ { - int num_caches; + int num_caches; POOL_SETMASK2(&BlockSig, &oldmask); pool_shmem_lock(); @@ -3253,14 +3349,13 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n } /* - * If we have something in the query cache buffer, that means - * either: - * - We only had SELECTs in the transaction - * - We had only SELECTs after last DML - * Thus we can register SELECT results to cache storage. + * If we have something in the query cache buffer, that means either: + * - We only had SELECTs in the transaction - We had only SELECTs + * after last DML Thus we can register SELECT results to cache + * storage. */ num_caches = session_context->query_cache_array->num_caches; - for (i=0;i<num_caches;i++) + for (i = 0; i < num_caches; i++) { POOL_TEMP_QUERY_CACHE *cache; @@ -3271,7 +3366,7 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n num_oids = cache->num_oids; oids = pool_get_buffer(cache->oids, &len); cache_buffer = pool_get_buffer(cache->buffer, &len); - + if (pool_commit_cache(backend, cache->query, cache_buffer, len, num_oids, oids) != 0) { ereport(WARNING, @@ -3290,7 +3385,7 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n pool_reset_memqcache_buffer(); } - else /* Non cache safe queries */ + else /* Non cache safe queries */ { /* Non cachable SELECT */ if (node && IsA(node, SelectStmt)) @@ -3307,13 +3402,15 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n pool_tmp_stats_count_up_num_selects(); } } + /* - * If the query is DROP DATABASE, discard both of caches in shmem/memcached and - * oidmap in memqcache_oiddir. + * If the query is DROP DATABASE, discard both of caches in + * shmem/memcached and oidmap in memqcache_oiddir. */ else if (is_drop_database(node) && session_context->query_context->dboid != 0) { - int dboid = session_context->query_context->dboid; + int dboid = session_context->query_context->dboid; + num_oids = pool_get_dropdb_table_oids(&oids, dboid); if (num_oids > 0 && pool_config->memqcache_auto_cache_invalidation) @@ -3326,7 +3423,7 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n pfree(oids); ereport(DEBUG2, - (errmsg("query cache handler for ReadyForQuery"), + (errmsg("query cache handler for ReadyForQuery"), errdetail("deleted all cache files for the DROPped DB"))); } } @@ -3341,8 +3438,8 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n if (num_oids > 0 && pool_config->memqcache_auto_cache_invalidation) { /* - * If we are not inside a transaction, we can - * immediately invalidate query cache. + * If we are not inside a transaction, we can immediately + * invalidate query cache. */ if (state == 'I') { @@ -3356,19 +3453,18 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n else { /* - * If we are inside a transaction, we - * cannot invalidate query cache - * yet. However we can clear cache buffer, - * if DML/DDL modifies the TABLE which SELECT uses. + * If we are inside a transaction, we cannot invalidate + * query cache yet. However we can clear cache buffer, if + * DML/DDL modifies the TABLE which SELECT uses. */ pool_check_and_discard_cache_buffer(num_oids, oids); - } + } } else if (num_oids == 0) { - /* - * It is also necessary to clear cache buffers in case of - * no oid queries (like BEGIN, CHECKPOINT, VACUUM, etc) too. + /* + * It is also necessary to clear cache buffers in case of no + * oid queries (like BEGIN, CHECKPOINT, VACUUM, etc) too. */ pool_reset_memqcache_buffer(); } @@ -3379,8 +3475,9 @@ void pool_handle_query_cache(POOL_CONNECTION_POOL *backend, char *query, Node *n /* * Create and initialize query cache stats */ -static POOL_QUERY_CACHE_STATS *stats; -int pool_init_memqcache_stats(void) +static POOL_QUERY_CACHE_STATS * stats; +int +pool_init_memqcache_stats(void) { stats = pool_shared_memory_create(sizeof(POOL_QUERY_CACHE_STATS)); pool_reset_memqcache_stats(); @@ -3391,7 +3488,8 @@ int pool_init_memqcache_stats(void) * Returns copy of stats area. The copy is in static area and will be * overwritten by next call to this function. */ -POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void) +POOL_QUERY_CACHE_STATS * +pool_get_memqcache_stats(void) { static POOL_QUERY_CACHE_STATS mystats; pool_sigset_t oldmask; @@ -3414,7 +3512,8 @@ POOL_QUERY_CACHE_STATS *pool_get_memqcache_stats(void) * Reset query cache stats. Caller must lock QUERY_CACHE_STATS_SEM if * necessary. */ -void pool_reset_memqcache_stats(void) +void +pool_reset_memqcache_stats(void) { memset(stats, 0, sizeof(POOL_QUERY_CACHE_STATS)); stats->start_time = time(NULL); @@ -3424,7 +3523,8 @@ void pool_reset_memqcache_stats(void) * Count up number of successful SELECTs and returns the number. * QUERY_CACHE_STATS_SEM lock is acquired in this function. */ -long long int pool_stats_count_up_num_selects(long long int num) +long long int +pool_stats_count_up_num_selects(long long int num) { pool_sigset_t oldmask; @@ -3440,19 +3540,21 @@ long long int pool_stats_count_up_num_selects(long long int num) * Count up number of successful SELECTs in temporary area and returns * the number. */ -long long int pool_tmp_stats_count_up_num_selects(void) +long long int +pool_tmp_stats_count_up_num_selects(void) { POOL_SESSION_CONTEXT *session_context; session_context = pool_get_session_context(false); session_context->num_selects++; - return session_context->num_selects; + return session_context->num_selects; } /* * Return number of successful SELECTs in temporary area. */ -long long int pool_tmp_stats_get_num_selects(void) +long long int +pool_tmp_stats_get_num_selects(void) { POOL_SESSION_CONTEXT *session_context; @@ -3463,7 +3565,8 @@ long long int pool_tmp_stats_get_num_selects(void) /* * Reset number of successful SELECTs in temporary area. */ -void pool_tmp_stats_reset_num_selects(void) +void +pool_tmp_stats_reset_num_selects(void) { POOL_SESSION_CONTEXT *session_context; @@ -3475,7 +3578,8 @@ void pool_tmp_stats_reset_num_selects(void) * Count up number of SELECTs extracted from cache returns the number. * QUERY_CACHE_STATS_SEM lock is acquired in this function. */ -long long int pool_stats_count_up_num_cache_hits(void) +long long int +pool_stats_count_up_num_cache_hits(void) { pool_sigset_t oldmask; @@ -3506,18 +3610,19 @@ static volatile POOL_HASH_ELEMENT *hash_free; */ #undef POOL_HASH_DEBUG -int pool_hash_init(int nelements) +int +pool_hash_init(int nelements) { - size_t size; - int nelements2; /* number of rounded up hash keys */ - int shift; - uint32 mask; + size_t size; + int nelements2; /* number of rounded up hash keys */ + int shift; + uint32 mask; POOL_HASH_HEADER hh; - int i; + int i; if (nelements <= 0) ereport(ERROR, - (errmsg("initializing hash table on shared memory, invalid number of elements: %d",nelements))); + (errmsg("initializing hash table on shared memory, invalid number of elements: %d", nelements))); /* Round up to power of 2 */ shift = 32; @@ -3530,32 +3635,32 @@ int pool_hash_init(int nelements) mask = ~0; mask >>= shift; - size = (char *)&hh.elements - (char *)&hh + sizeof(POOL_HEADER_ELEMENT)*nelements2; + size = (char *) &hh.elements - (char *) &hh + sizeof(POOL_HEADER_ELEMENT) * nelements2; hash_header = pool_shared_memory_create(size); hash_header->nhash = nelements2; - hash_header->mask = mask; + hash_header->mask = mask; #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("initializing hash table on shared memory"), + (errmsg("initializing hash table on shared memory"), errdetail("size:%zd nelements2:%d", size, nelements2))); #endif - size = sizeof(POOL_HASH_ELEMENT)*nelements2; + size = sizeof(POOL_HASH_ELEMENT) * nelements2; hash_elements = pool_shared_memory_create(size); #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("initializing hash table on shared memory"), + (errmsg("initializing hash table on shared memory"), errdetail("size:%zd nelements2:%d", size, nelements2))); #endif - for (i=0;i<nelements2-1;i++) + for (i = 0; i < nelements2 - 1; i++) { - hash_elements[i].next = (POOL_HASH_ELEMENT *)&hash_elements[i+1]; + hash_elements[i].next = (POOL_HASH_ELEMENT *) & hash_elements[i + 1]; } - hash_elements[nelements2-1].next = NULL; + hash_elements[nelements2 - 1].next = NULL; hash_free = hash_elements; return 0; @@ -3569,16 +3674,16 @@ int pool_hash_init(int nelements) static int pool_hash_reset(int nelements) { - size_t size; - int nelements2; /* number of rounded up hash keys */ - int shift; - uint32 mask; + size_t size; + int nelements2; /* number of rounded up hash keys */ + int shift; + uint32 mask; POOL_HASH_HEADER hh; - int i; + int i; if (nelements <= 0) ereport(ERROR, - (errmsg("clearing hash table on shared memory, invalid number of elements: %d",nelements))); + (errmsg("clearing hash table on shared memory, invalid number of elements: %d", nelements))); /* Round up to power of 2 */ shift = 32; @@ -3592,20 +3697,20 @@ pool_hash_reset(int nelements) mask = ~0; mask >>= shift; - size = (char *)&hh.elements - (char *)&hh + sizeof(POOL_HEADER_ELEMENT)*nelements2; - memset((void *)hash_header, 0, size); + size = (char *) &hh.elements - (char *) &hh + sizeof(POOL_HEADER_ELEMENT) * nelements2; + memset((void *) hash_header, 0, size); hash_header->nhash = nelements2; - hash_header->mask = mask; + hash_header->mask = mask; - size = sizeof(POOL_HASH_ELEMENT)*nelements2; - memset((void *)hash_elements, 0, size); + size = sizeof(POOL_HASH_ELEMENT) * nelements2; + memset((void *) hash_elements, 0, size); - for (i=0;i<nelements2-1;i++) + for (i = 0; i < nelements2 - 1; i++) { - hash_elements[i].next = (POOL_HASH_ELEMENT *)&hash_elements[i+1]; + hash_elements[i].next = (POOL_HASH_ELEMENT *) & hash_elements[i + 1]; } - hash_elements[nelements2-1].next = NULL; + hash_elements[nelements2 - 1].next = NULL; hash_free = hash_elements; return 0; @@ -3615,28 +3720,30 @@ pool_hash_reset(int nelements) * Search cacheid by MD5 hash key string * If found, returns cache id, otherwise NULL. */ -POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key) +POOL_CACHEID * +pool_hash_search(POOL_QUERY_HASH * key) { - volatile POOL_HASH_ELEMENT *element; + volatile POOL_HASH_ELEMENT *element; - uint32 hash_key = create_hash_key(key); + uint32 hash_key = create_hash_key(key); if (hash_key >= hash_header->nhash) { ereport(WARNING, - (errmsg("memcache: searching cacheid from hash. invalid hash key"), - errdetail("invalid hash key: %uld nhash: %ld", - hash_key, hash_header->nhash))); + (errmsg("memcache: searching cacheid from hash. invalid hash key"), + errdetail("invalid hash key: %uld nhash: %ld", + hash_key, hash_header->nhash))); return NULL; } { - char md5[POOL_MD5_HASHKEYLEN+1]; + char md5[POOL_MD5_HASHKEYLEN + 1]; + memcpy(md5, key->query_hash, POOL_MD5_HASHKEYLEN); md5[POOL_MD5_HASHKEYLEN] = '\0'; #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("searching hash table"), + (errmsg("searching hash table"), errdetail("hash_key:%d md5:%s", hash_key, md5))); #endif } @@ -3645,20 +3752,21 @@ POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key) while (element) { { - char md5[POOL_MD5_HASHKEYLEN+1]; + char md5[POOL_MD5_HASHKEYLEN + 1]; + memcpy(md5, key->query_hash, POOL_MD5_HASHKEYLEN); md5[POOL_MD5_HASHKEYLEN] = '\0'; #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("searching hash table"), + (errmsg("searching hash table"), errdetail("element md5:%s", md5))); #endif } - if (memcmp((const void *)element->hashkey.query_hash, - (const void *)key->query_hash, sizeof(key->query_hash)) == 0) + if (memcmp((const void *) element->hashkey.query_hash, + (const void *) key->query_hash, sizeof(key->query_hash)) == 0) { - return (POOL_CACHEID *)&element->cacheid; + return (POOL_CACHEID *) & element->cacheid; } element = element->next; } @@ -3670,29 +3778,31 @@ POOL_CACHEID *pool_hash_search(POOL_QUERY_HASH *key) * "update" is true, replace cacheid associated with the MD5 key, * rather than throw an error. */ -static int pool_hash_insert(POOL_QUERY_HASH *key, POOL_CACHEID *cacheid, bool update) +static int +pool_hash_insert(POOL_QUERY_HASH * key, POOL_CACHEID * cacheid, bool update) { POOL_HASH_ELEMENT *element; POOL_HASH_ELEMENT *new_element; - uint32 hash_key = create_hash_key(key); + uint32 hash_key = create_hash_key(key); if (hash_key >= hash_header->nhash) { ereport(WARNING, - (errmsg("memcache: adding cacheid to hash. invalid hash key"), + (errmsg("memcache: adding cacheid to hash. invalid hash key"), errdetail("invalid hash key: %uld nhash: %ld", hash_key, hash_header->nhash))); return -1; } { - char md5[POOL_MD5_HASHKEYLEN+1]; + char md5[POOL_MD5_HASHKEYLEN + 1]; + memcpy(md5, key->query_hash, POOL_MD5_HASHKEYLEN); md5[POOL_MD5_HASHKEYLEN] = '\0'; #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("searching hash table"), + (errmsg("searching hash table"), errdetail("hash_key:%d md5:%s block:%d item:%d", hash_key, md5, cacheid->blockid, cacheid->itemid))); #endif } @@ -3704,24 +3814,24 @@ static int pool_hash_insert(POOL_QUERY_HASH *key, POOL_CACHEID *cacheid, bool up while (element) { - if (memcmp((const void *)element->hashkey.query_hash, - (const void *)key->query_hash, sizeof(key->query_hash)) == 0) + if (memcmp((const void *) element->hashkey.query_hash, + (const void *) key->query_hash, sizeof(key->query_hash)) == 0) { /* Hash key found. If "update" is false, just throw an error. */ - char md5[POOL_MD5_HASHKEYLEN+1]; + char md5[POOL_MD5_HASHKEYLEN + 1]; if (!update) { memcpy(md5, key->query_hash, POOL_MD5_HASHKEYLEN); md5[POOL_MD5_HASHKEYLEN] = '\0'; ereport(LOG, - (errmsg("memcache: adding cacheid to hash. hash key:\"%s\" already exists",md5))); + (errmsg("memcache: adding cacheid to hash. hash key:\"%s\" already exists", md5))); return -1; } else { /* Update cache id */ - memcpy((void *)&element->cacheid, cacheid, sizeof(POOL_CACHEID)); + memcpy((void *) &element->cacheid, cacheid, sizeof(POOL_CACHEID)); return 0; } } @@ -3731,7 +3841,7 @@ static int pool_hash_insert(POOL_QUERY_HASH *key, POOL_CACHEID *cacheid, bool up /* * Ok, same key did not exist. Just insert new hash key. */ - new_element = (POOL_HASH_ELEMENT *)get_new_hash_element(); + new_element = (POOL_HASH_ELEMENT *) get_new_hash_element(); if (!new_element) { ereport(LOG, @@ -3744,8 +3854,8 @@ static int pool_hash_insert(POOL_QUERY_HASH *key, POOL_CACHEID *cacheid, bool up hash_header->elements[hash_key].element = new_element; new_element->next = element; - memcpy((void *)new_element->hashkey.query_hash, key->query_hash, POOL_MD5_HASHKEYLEN); - memcpy((void *)&new_element->cacheid, cacheid, sizeof(POOL_CACHEID)); + memcpy((void *) new_element->hashkey.query_hash, key->query_hash, POOL_MD5_HASHKEYLEN); + memcpy((void *) &new_element->cacheid, cacheid, sizeof(POOL_CACHEID)); return 0; } @@ -3753,18 +3863,19 @@ static int pool_hash_insert(POOL_QUERY_HASH *key, POOL_CACHEID *cacheid, bool up /* * Delete MD5 key and associated cache id into shmem hash table. */ -int pool_hash_delete(POOL_QUERY_HASH *key) +int +pool_hash_delete(POOL_QUERY_HASH * key) { POOL_HASH_ELEMENT *element; POOL_HASH_ELEMENT **delete_point; - bool found; + bool found; - uint32 hash_key = create_hash_key(key); + uint32 hash_key = create_hash_key(key); if (hash_key >= hash_header->nhash) { ereport(LOG, - (errmsg("memcache: deleting key from hash. invalid key"), + (errmsg("memcache: deleting key from hash. invalid key"), errdetail("invalid hash key: %uld nhash: %ld", hash_key, hash_header->nhash))); return -1; @@ -3774,7 +3885,7 @@ int pool_hash_delete(POOL_QUERY_HASH *key) * Look for delete location */ found = false; - delete_point = (POOL_HASH_ELEMENT **)&(hash_header->elements[hash_key].element); + delete_point = (POOL_HASH_ELEMENT * *) & (hash_header->elements[hash_key].element); element = hash_header->elements[hash_key].element; while (element) @@ -3790,12 +3901,12 @@ int pool_hash_delete(POOL_QUERY_HASH *key) if (!found) { - char md5[POOL_MD5_HASHKEYLEN+1]; + char md5[POOL_MD5_HASHKEYLEN + 1]; memcpy(md5, key->query_hash, POOL_MD5_HASHKEYLEN); md5[POOL_MD5_HASHKEYLEN] = '\0'; ereport(LOG, - (errmsg("memcache: deleting key from hash. key:\"%s\" not found",md5))); + (errmsg("memcache: deleting key from hash. key:\"%s\" not found", md5))); return -1; } @@ -3808,16 +3919,17 @@ int pool_hash_delete(POOL_QUERY_HASH *key) return 0; } -/* +/* * Calculate 32bit binary hash key(i.e. location in hash header) from MD5 * string. We use top most 8 characters of MD5 string for calculation. */ -static uint32 create_hash_key(POOL_QUERY_HASH *key) +static uint32 +create_hash_key(POOL_QUERY_HASH * key) { #define POOL_HASH_NCHARS 8 - char md5[POOL_HASH_NCHARS+1]; - uint32 mask; + char md5[POOL_HASH_NCHARS + 1]; + uint32 mask; memcpy(md5, key->query_hash, POOL_HASH_NCHARS); md5[POOL_HASH_NCHARS] = '\0'; @@ -3829,9 +3941,10 @@ static uint32 create_hash_key(POOL_QUERY_HASH *key) /* * Get new free hash element from free list. */ -static volatile POOL_HASH_ELEMENT *get_new_hash_element(void) +static volatile POOL_HASH_ELEMENT * +get_new_hash_element(void) { - volatile POOL_HASH_ELEMENT *elm; + volatile POOL_HASH_ELEMENT *elm; if (!hash_free->next) { @@ -3841,9 +3954,9 @@ static volatile POOL_HASH_ELEMENT *get_new_hash_element(void) #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("getting new hash element"), - errdetail("hash_free->next:%p hash_free->next->next:%p", - hash_free->next, hash_free->next->next))); + (errmsg("getting new hash element"), + errdetail("hash_free->next:%p hash_free->next->next:%p", + hash_free->next, hash_free->next->next))); #endif elm = hash_free->next; @@ -3855,26 +3968,28 @@ static volatile POOL_HASH_ELEMENT *get_new_hash_element(void) /* * Put back hash element to free list. */ -static void put_back_hash_element(volatile POOL_HASH_ELEMENT *element) +static void +put_back_hash_element(volatile POOL_HASH_ELEMENT * element) { POOL_HASH_ELEMENT *elm; #ifdef POOL_HASH_DEBUG ereport(LOG, - (errmsg("getting new hash element"), - errdetail("hash_free->next:%p hash_free->next->next:%p", - hash_free->next, hash_free->next->next))); + (errmsg("getting new hash element"), + errdetail("hash_free->next:%p hash_free->next->next:%p", + hash_free->next, hash_free->next->next))); #endif elm = hash_free->next; - hash_free->next = (POOL_HASH_ELEMENT *)element; + hash_free->next = (POOL_HASH_ELEMENT *) element; element->next = elm; } /* * Return true if there's a free hash element. */ -static bool is_free_hash_element(void) +static bool +is_free_hash_element(void) { return hash_free->next != NULL; } @@ -3886,16 +4001,17 @@ static bool is_free_hash_element(void) * Caller must hold shmem_lock before calling this function. * If in memory query cache is not enabled, all stats are 0. */ -POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void) +POOL_SHMEM_STATS * +pool_get_shmem_storage_stats(void) { static POOL_SHMEM_STATS mystats; POOL_HASH_ELEMENT *element; - int nblocks; - int i; + int nblocks; + int i; memset(&mystats, 0, sizeof(POOL_SHMEM_STATS)); - if (!pool_config-> memory_cache_enabled) + if (!pool_config->memory_cache_enabled) return &mystats; /* @@ -3911,7 +4027,7 @@ POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void) mystats.num_hash_entries = hash_header->nhash; /* number of used hash entries */ - for (i=0;i<hash_header->nhash;i++) + for (i = 0; i < hash_header->nhash; i++) { element = hash_header->elements[i].element; while (element) @@ -3923,17 +4039,18 @@ POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void) nblocks = pool_get_memqcache_blocks(); - for (i=0;i<nblocks;i++) + for (i = 0; i < nblocks; i++) { POOL_CACHE_BLOCK_HEADER *bh; POOL_CACHE_ITEM_POINTER *cip; - char *p = block_address(i); - bh = (POOL_CACHE_BLOCK_HEADER *)p; - int j; + char *p = block_address(i); + + bh = (POOL_CACHE_BLOCK_HEADER *) p; + int j; if (bh->flags & POOL_BLOCK_USED) { - for (j=0;j<bh->num_items;j++) + for (j = 0; j < bh->num_items; j++) { cip = item_pointer(p, j); if (POOL_ITEM_DELETED & cip->flags) @@ -3970,16 +4087,17 @@ POOL_SHMEM_STATS *pool_get_shmem_storage_stats(void) * Inject cached message to the target backend buffer to pretend as if backend * actually replies with Data row and Command Complete message. */ -static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qcachelen) +static void +inject_cached_message(POOL_CONNECTION * backend, char *qcache, int qcachelen) { - char kind; - int len; - char *buf; - int timeout; - int i = 0; - bool is_prepared_stmt = false; + char kind; + int len; + char *buf; + int timeout; + int i = 0; + bool is_prepared_stmt = false; POOL_SESSION_CONTEXT *session_context; - POOL_QUERY_CONTEXT* query_context; + POOL_QUERY_CONTEXT *query_context; POOL_PENDING_MESSAGE *msg; session_context = pool_get_session_context(false); @@ -3991,7 +4109,7 @@ static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qc /* * If pending message found, we should extract target backend from it */ - int backend_id; + int backend_id; backend_id = pool_pending_message_get_target_backend_id(msg); backend = CONNECTION(session_context->backend, backend_id); @@ -4001,14 +4119,14 @@ static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qc timeout = 0; /* Send flush messsage to backend to retrieve response of backend */ - pool_write(backend, "H", 1); + pool_write(backend, "H", 1); len = htonl(sizeof(len)); pool_write_and_flush(backend, &len, sizeof(len)); /* * Push any response from backend */ - for(;;) + for (;;) { pool_read(backend, &kind, 1); ereport(DEBUG1, @@ -4023,10 +4141,10 @@ static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qc pool_push(backend, &kind, sizeof(kind)); pool_read(backend, &len, sizeof(len)); pool_push(backend, &len, sizeof(len)); - if ((ntohl(len)-sizeof(len)) > 0) + if ((ntohl(len) - sizeof(len)) > 0) { - buf = pool_read2(backend, ntohl(len)-sizeof(len)); - pool_push(backend, buf, ntohl(len)-sizeof(len)); + buf = pool_read2(backend, ntohl(len) - sizeof(len)); + pool_push(backend, buf, ntohl(len) - sizeof(len)); } /* check if there's any pending data */ @@ -4049,14 +4167,14 @@ static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qc */ while (i < qcachelen) { - char tmpkind; - int tmplen; - char *p; + char tmpkind; + int tmplen; + char *p; tmpkind = qcache[i]; i++; - memcpy(&tmplen, qcache+i, sizeof(tmplen)); + memcpy(&tmplen, qcache + i, sizeof(tmplen)); i += sizeof(tmplen); len = ntohl(tmplen); p = qcache + i; @@ -4070,8 +4188,8 @@ static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qc } /* - * In the prepared statement execution, there is no need to send - * 'T' response to the frontend. + * In the prepared statement execution, there is no need to send 'T' + * response to the frontend. */ if (is_prepared_stmt && tmpkind == 'T') { @@ -4080,7 +4198,7 @@ static void inject_cached_message(POOL_CONNECTION *backend, char *qcache, int qc /* push message */ ereport(DEBUG1, - (errmsg("inject_cached_message: push cached messages: '%c' len: %d", tmpkind, len))); + (errmsg("inject_cached_message: push cached messages: '%c' len: %d", tmpkind, len))); pool_push(backend, &tmpkind, 1); pool_push(backend, &tmplen, sizeof(tmplen)); if (len > 0) diff --git a/src/rewrite/pool_lobj.c b/src/rewrite/pool_lobj.c index 0e235d3c2..e13debad7 100644 --- a/src/rewrite/pool_lobj.c +++ b/src/rewrite/pool_lobj.c @@ -50,8 +50,9 @@ * length. This is allocated in a static memory. New packet length is * set to *len. */ -char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, - POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, int* len) +char * +pool_rewrite_lo_creat(char kind, char *packet, int packet_len, + POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, int *len) { #define LO_CREAT_OID_QUERY "SELECT oid FROM pg_catalog.pg_proc WHERE proname = 'lo_creat' and pronamespace = (SELECT oid FROM pg_catalog.pg_namespace WHERE nspname = 'pg_catalog')" @@ -63,31 +64,31 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, #define GET_MAX_LOBJ_KEY "SELECT coalesce(max(loid)::INTEGER, 0)+1 FROM pg_catalog.pg_largeobject" - static char rewritten_packet[LO_CREATE_PACKET_LENGTH]; + static char rewritten_packet[LO_CREATE_PACKET_LENGTH]; - static POOL_RELCACHE *relcache_lo_creat; - static POOL_RELCACHE *relcache_lo_create; + static POOL_RELCACHE * relcache_lo_creat; + static POOL_RELCACHE * relcache_lo_create; - int lo_creat_oid; - int lo_create_oid; - int orig_fcall_oid; + int lo_creat_oid; + int lo_create_oid; + int orig_fcall_oid; POOL_STATUS status; - char qbuf[1024]; - char *p; + char qbuf[1024]; + char *p; POOL_SELECT_RESULT *result; - int lobjid; - int32 int32val; - int16 int16val; - int16 result_format_code; + int lobjid; + int32 int32val; + int16 int16val; + int16 result_format_code; if (kind != 'F') - return NULL; /* not function call */ + return NULL; /* not function call */ - if (!strcmp(pool_config->lobj_lock_table,"")) - return NULL; /* no lock table */ + if (!strcmp(pool_config->lobj_lock_table, "")) + return NULL; /* no lock table */ if (!REPLICATION) - return NULL; /* not in replication mode */ + return NULL; /* not in replication mode */ /* * If relcache does not exist, create it. @@ -95,12 +96,12 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, if (!relcache_lo_creat) { relcache_lo_creat = pool_create_relcache(1, LO_CREAT_OID_QUERY, - int_register_func, int_unregister_func, - false); + int_register_func, int_unregister_func, + false); if (relcache_lo_creat == NULL) { ereport(WARNING, - (errmsg("unable to create relcache, while rewriting LO CREATE"))); + (errmsg("unable to create relcache, while rewriting LO CREATE"))); return NULL; } } @@ -108,17 +109,18 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, /* * Get lo_creat oid */ - lo_creat_oid = (int)(intptr_t)pool_search_relcache(relcache_lo_creat, backend, "pg_proc"); + lo_creat_oid = (int) (intptr_t) pool_search_relcache(relcache_lo_creat, backend, "pg_proc"); memmove(&orig_fcall_oid, packet, sizeof(int32)); orig_fcall_oid = ntohl(orig_fcall_oid); ereport(DEBUG1, - (errmsg("rewriting LO CREATE"), + (errmsg("rewriting LO CREATE"), errdetail("orig_fcall_oid:% d lo_creat_oid: %d", orig_fcall_oid, lo_creat_oid))); /* - * This function call is calling lo_creat? */ + * This function call is calling lo_creat? + */ if (orig_fcall_oid != lo_creat_oid) return NULL; @@ -128,8 +130,8 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, if (!relcache_lo_create) { relcache_lo_create = pool_create_relcache(1, LO_CREATE_OID_QUERY, - int_register_func, int_unregister_func, - false); + int_register_func, int_unregister_func, + false); if (relcache_lo_create == NULL) { ereport(LOG, @@ -141,16 +143,16 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, /* * Get lo_create oid */ - lo_create_oid = (int)(intptr_t)pool_search_relcache(relcache_lo_create, backend, "pg_proc"); + lo_create_oid = (int) (intptr_t) pool_search_relcache(relcache_lo_create, backend, "pg_proc"); ereport(DEBUG1, - (errmsg("rewriting LO CREATE"), - errdetail("lo_creat_oid: %d lo_create_oid: %d",lo_creat_oid, lo_create_oid))); + (errmsg("rewriting LO CREATE"), + errdetail("lo_creat_oid: %d lo_create_oid: %d", lo_creat_oid, lo_create_oid))); /* * Parse input packet */ - memmove(&int16val, packet+packet_len-sizeof(int16), sizeof(int16)); + memmove(&int16val, packet + packet_len - sizeof(int16), sizeof(int16)); result_format_code = ntohs(int16val); /* sanity check */ @@ -161,7 +163,7 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, return NULL; } ereport(DEBUG1, - (errmsg("rewriting LO CREATE"), + (errmsg("rewriting LO CREATE"), errdetail("return format code: %d", int16val))); /* @@ -185,7 +187,7 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, if (TSTATE(backend, MASTER_NODE_ID) == 'E') { ereport(LOG, - (errmsg("failed while rewriting LO CREATE"), + (errmsg("failed while rewriting LO CREATE"), errdetail("failed to execute: %s", qbuf))); return NULL; } @@ -197,14 +199,14 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, if (!result) { ereport(LOG, - (errmsg("failed while rewriting LO CREATE"), + (errmsg("failed while rewriting LO CREATE"), errdetail("failed to execute: %s", GET_MAX_LOBJ_KEY))); return NULL; } - + lobjid = atoi(result->data[0]); ereport(DEBUG1, - (errmsg("rewriting LO CREATE"), + (errmsg("rewriting LO CREATE"), errdetail("lobjid:%d", lobjid))); free_select_result(result); @@ -225,31 +227,31 @@ char *pool_rewrite_lo_creat(char kind, char *packet, int packet_len, *len = LO_CREATE_PACKET_LENGTH; int32val = htonl(lo_create_oid); - memmove(p,&int32val, sizeof(int32)); /* lo_create oid */ + memmove(p, &int32val, sizeof(int32)); /* lo_create oid */ p += sizeof(int32); int16val = htons(1); - memmove(p,&int16val, sizeof(int16)); /* number of argument format code */ + memmove(p, &int16val, sizeof(int16)); /* number of argument format code */ p += sizeof(int16); int16val = htons(1); - memmove(p,&int16val, sizeof(int16)); /* format code */ + memmove(p, &int16val, sizeof(int16)); /* format code */ p += sizeof(int16); int16val = htons(1); - memmove(p,&int16val, sizeof(int16)); /* number of arguments */ + memmove(p, &int16val, sizeof(int16)); /* number of arguments */ p += sizeof(int16); int32val = htonl(4); - memmove(p,&int32val, sizeof(int32)); /* argument length */ + memmove(p, &int32val, sizeof(int32)); /* argument length */ p += sizeof(int32); int32val = htonl(lobjid); - memmove(p,&int32val, sizeof(int32)); /* argument(lobj id) */ + memmove(p, &int32val, sizeof(int32)); /* argument(lobj id) */ p += sizeof(int32); int16val = htons(result_format_code); - memmove(p,&int16val, sizeof(int16)); /* result format code */ + memmove(p, &int16val, sizeof(int16)); /* result format code */ return rewritten_packet; } diff --git a/src/rewrite/pool_timestamp.c b/src/rewrite/pool_timestamp.c index 925142893..b6c2c4b47 100644 --- a/src/rewrite/pool_timestamp.c +++ b/src/rewrite/pool_timestamp.c @@ -35,51 +35,56 @@ #include "utils/memutils.h" #include "context/pool_session_context.h" -typedef struct { - char *attrname; /* attribute name */ - char *adsrc; /* default value expression */ - int use_timestamp; /* not zero if timestamp is used in default value */ -} TSAttr; - -typedef struct { - int relnatts; /* num of attributes */ - TSAttr attr[1]; -} TSRel; - -typedef struct { - A_Const *ts_const; - POOL_CONNECTION_POOL *backend; - char *relname; - int num_params; /* num of original params (for Parse) */ - bool rewrite_to_params; /* true if timestamp is rewritten to param insread of const */ - bool rewrite; /* has rewritten? */ - List *params; /* list of additional params */ -} TSRewriteContext; - -static void *ts_register_func(POOL_SELECT_RESULT *res); +typedef struct +{ + char *attrname; /* attribute name */ + char *adsrc; /* default value expression */ + int use_timestamp; /* not zero if timestamp is used in default + * value */ +} TSAttr; + +typedef struct +{ + int relnatts; /* num of attributes */ + TSAttr attr[1]; +} TSRel; + +typedef struct +{ + A_Const *ts_const; + POOL_CONNECTION_POOL *backend; + char *relname; + int num_params; /* num of original params (for Parse) */ + bool rewrite_to_params; /* true if timestamp is rewritten to param + * insread of const */ + bool rewrite; /* has rewritten? */ + List *params; /* list of additional params */ +} TSRewriteContext; + +static void *ts_register_func(POOL_SELECT_RESULT * res); static void *ts_unregister_func(void *data); -static TSRel *relcache_lookup(TSRewriteContext *ctx); +static TSRel * relcache_lookup(TSRewriteContext * ctx); static bool isStringConst(Node *node, const char *str); static bool rewrite_timestamp_walker(Node *node, void *context); -static bool rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx); -static bool rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx); -static char *get_current_timestamp(POOL_CONNECTION_POOL *backend); -static Node *makeTsExpr(TSRewriteContext *ctx); +static bool rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext * ctx); +static bool rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext * ctx); +static char *get_current_timestamp(POOL_CONNECTION_POOL * backend); +static Node *makeTsExpr(TSRewriteContext * ctx); static TypeCast *makeTypeCastFromSvfOp(SQLValueFunctionOp op); -static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression); -bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context); +static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL * backend, char *expression); +bool raw_expression_tree_walker(Node *node, bool (*walker) (), void *context); -POOL_RELCACHE *ts_relcache; +POOL_RELCACHE *ts_relcache; static void * -ts_register_func(POOL_SELECT_RESULT *res) +ts_register_func(POOL_SELECT_RESULT * res) { /* Number of result columns included in res */ #define NUM_COLS 3 - TSRel *rel; - int i; + TSRel *rel; + int i; if (res->numrows == 0) return NULL; @@ -88,7 +93,7 @@ ts_register_func(POOL_SELECT_RESULT *res) for (i = 0; i < res->numrows; i++) { - int index = 0; + int index = 0; /* attribute name */ rel->attr[i].attrname = strdup(res->data[i * NUM_COLS + index]); @@ -105,10 +110,10 @@ ts_register_func(POOL_SELECT_RESULT *res) /* if timestamp is used in default value */ rel->attr[i].use_timestamp = *(res->data[i * NUM_COLS + index]) == 't'; ereport(DEBUG1, - (errmsg("timestamp register function"), - errdetail("attrname %s adsrc %s use_timestamp = %d", - rel->attr[i].attrname, (rel->attr[i].adsrc? rel->attr[i].adsrc:"NULL"), - rel->attr[i].use_timestamp))); + (errmsg("timestamp register function"), + errdetail("attrname %s adsrc %s use_timestamp = %d", + rel->attr[i].attrname, (rel->attr[i].adsrc ? rel->attr[i].adsrc : "NULL"), + rel->attr[i].use_timestamp))); } /* num of attributes */ @@ -120,15 +125,16 @@ ts_register_func(POOL_SELECT_RESULT *res) static void * ts_unregister_func(void *data) { - TSRel *rel = (TSRel *) data; + TSRel *rel = (TSRel *) data; + if (rel) free(rel); - return (void *)0; + return (void *) 0; } -static TSRel* -relcache_lookup(TSRewriteContext *ctx) +static TSRel * +relcache_lookup(TSRewriteContext * ctx) { #define ATTRDEFQUERY "SELECT attname, d.adsrc, coalesce((d.adsrc LIKE '%%now()%%' OR d.adsrc LIKE '%%''now''::text%%' OR" \ " d.adsrc LIKE '%%CURRENT_TIMESTAMP%%' OR d.adsrc LIKE '%%CURRENT_TIME%%' OR d.adsrc LIKE '%%CURRENT_DATE%%' OR" \ @@ -172,8 +178,8 @@ relcache_lookup(TSRewriteContext *ctx) " WHERE c.oid = a.attrelid AND a.attnum >= 1 AND a.attisdropped = 'f' AND c.oid = to_regclass('%s')" \ " ORDER BY a.attnum" - char *query; - char *table_name; + char *query; + char *table_name; table_name = ctx->relname; @@ -198,7 +204,7 @@ relcache_lookup(TSRewriteContext *ctx) if (ts_relcache == NULL) { ereport(WARNING, - (errmsg("unable to create relcache"))); + (errmsg("unable to create relcache"))); return NULL; } } @@ -211,9 +217,9 @@ relcache_lookup(TSRewriteContext *ctx) * and add it into params list in context. */ static Node * -makeTsExpr(TSRewriteContext *ctx) +makeTsExpr(TSRewriteContext * ctx) { - ParamRef *param; + ParamRef *param; if (!ctx->rewrite_to_params) return (Node *) ctx->ts_const; @@ -228,7 +234,7 @@ makeTsExpr(TSRewriteContext *ctx) static bool isStringConst(Node *node, const char *str) { - A_Const *a_const; + A_Const *a_const; Value val; if (!IsA(node, A_Const)) @@ -247,7 +253,7 @@ isStringConst(Node *node, const char *str) bool isSystemType(Node *node, const char *name) { - TypeName *typename; + TypeName *typename; if (!IsA(node, TypeName)) return false; @@ -265,7 +271,7 @@ isSystemType(Node *node, const char *name) static bool isSystemTypeCast(Node *node, const char *name) { - TypeCast *typecast; + TypeCast *typecast; if (!IsA(node, TypeCast)) return false; @@ -280,7 +286,7 @@ isSystemTypeCast(Node *node, const char *name) static bool rewrite_timestamp_walker(Node *node, void *context) { - TSRewriteContext *ctx = (TSRewriteContext *) context; + TSRewriteContext *ctx = (TSRewriteContext *) context; if (node == NULL) return false; @@ -289,8 +295,8 @@ rewrite_timestamp_walker(Node *node, void *context) { case T_InsertStmt: { - TSRewriteContext *ctx = (TSRewriteContext *) context; - char *relname_old; + TSRewriteContext *ctx = (TSRewriteContext *) context; + char *relname_old; InsertStmt *i_stmt = (InsertStmt *) node; relname_old = ctx->relname; @@ -302,8 +308,8 @@ rewrite_timestamp_walker(Node *node, void *context) return false; case T_UpdateStmt: { - TSRewriteContext *ctx = (TSRewriteContext *) context; - char *relname_old; + TSRewriteContext *ctx = (TSRewriteContext *) context; + char *relname_old; UpdateStmt *u_stmt = (UpdateStmt *) node; relname_old = ctx->relname; @@ -316,15 +322,16 @@ rewrite_timestamp_walker(Node *node, void *context) case T_FuncCall: { /* `now()' FuncCall */ - FuncCall *fcall = (FuncCall *) node; + FuncCall *fcall = (FuncCall *) node; if ((list_length(fcall->funcname) == 1 && - strcmp("now", strVal(linitial(fcall->funcname))) == 0) || + strcmp("now", strVal(linitial(fcall->funcname))) == 0) || (list_length(fcall->funcname) == 2 && - strcmp("pg_catalog", strVal(linitial(fcall->funcname))) == 0 && - strcmp("now", strVal(lsecond(fcall->funcname))) == 0)) + strcmp("pg_catalog", strVal(linitial(fcall->funcname))) == 0 && + strcmp("now", strVal(lsecond(fcall->funcname))) == 0)) { - TypeCast *tc = makeNode(TypeCast); + TypeCast *tc = makeNode(TypeCast); + tc->arg = makeTsExpr(ctx); tc->typeName = SystemTypeName("text"); @@ -337,13 +344,14 @@ rewrite_timestamp_walker(Node *node, void *context) case T_SQLValueFunction: { - /* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc. + /* + * CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc. * From PostgreSQL 10, timestamp conversion is changed and - * SQLValueFunction is added. But Pgpool-II should use - * the old timestamp translate like "'now'::text::date". - * So we have to cast the node to TypeCast first. + * SQLValueFunction is added. But Pgpool-II should use the old + * timestamp translate like "'now'::text::date". So we have to + * cast the node to TypeCast first. */ - SQLValueFunction *svf = (SQLValueFunction *) node; + SQLValueFunction *svf = (SQLValueFunction *) node; if (svf->op == SVFOP_CURRENT_DATE || svf->op == SVFOP_CURRENT_TIME || @@ -356,18 +364,22 @@ rewrite_timestamp_walker(Node *node, void *context) svf->op == SVFOP_LOCALTIMESTAMP_N) { - TypeCast *tc, *tc1; + TypeCast *tc, + *tc1; tc1 = makeTypeCastFromSvfOp(svf->op); tc = (TypeCast *) node; tc->arg = tc1->arg; - tc->typeName = (TypeName *)copyObject(tc1->typeName); + tc->typeName = (TypeName *) copyObject(tc1->typeName); tc->location = -1; node->type = T_TypeCast; - /* rewrite `'now'::timestamp' and `'now'::text::timestamp' both */ + /* + * rewrite `'now'::timestamp' and `'now'::text::timestamp' + * both + */ if (isSystemTypeCast(tc->arg, "text")) tc = (TypeCast *) tc->arg; @@ -384,12 +396,15 @@ rewrite_timestamp_walker(Node *node, void *context) TypeCast *tc = (TypeCast *) node; if ((isSystemType((Node *) tc->typeName, "date") || - isSystemType((Node *) tc->typeName, "timestamp") || - isSystemType((Node *) tc->typeName, "timestamptz") || - isSystemType((Node *) tc->typeName, "time") || - isSystemType((Node *) tc->typeName, "timetz"))) + isSystemType((Node *) tc->typeName, "timestamp") || + isSystemType((Node *) tc->typeName, "timestamptz") || + isSystemType((Node *) tc->typeName, "time") || + isSystemType((Node *) tc->typeName, "timetz"))) { - /* rewrite `'now'::timestamp' and `'now'::text::timestamp' both */ + /* + * rewrite `'now'::timestamp' and `'now'::text::timestamp' + * both + */ if (isSystemTypeCast(tc->arg, "text")) tc = (TypeCast *) tc->arg; @@ -403,7 +418,7 @@ rewrite_timestamp_walker(Node *node, void *context) break; case T_ParamRef: { - ParamRef *param = (ParamRef *) node; + ParamRef *param = (ParamRef *) node; /* count how many params in original query */ if (ctx->num_params < param->number) @@ -422,10 +437,10 @@ rewrite_timestamp_walker(Node *node, void *context) * Get `now()' from MASTER node */ static char * -get_current_timestamp(POOL_CONNECTION_POOL *backend) +get_current_timestamp(POOL_CONNECTION_POOL * backend) { POOL_SELECT_RESULT *res; - static char timestamp[64]; + static char timestamp[64]; do_query(MASTER(backend), "SELECT now()", &res, MAJOR(backend)); @@ -446,35 +461,34 @@ get_current_timestamp(POOL_CONNECTION_POOL *backend) * rewrite InsertStmt */ static bool -rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) +rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext * ctx) { - int i; - bool rewrite = false; - TSRel *relcache; + int i; + bool rewrite = false; + TSRel *relcache; raw_expression_tree_walker( - (Node *) i_stmt->withClause, - rewrite_timestamp_walker, (void *) ctx); + (Node *) i_stmt->withClause, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( - (Node *) i_stmt->onConflictClause, - rewrite_timestamp_walker, (void *) ctx); + (Node *) i_stmt->onConflictClause, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( - (Node *) i_stmt->returningList, - rewrite_timestamp_walker, (void *) ctx); + (Node *) i_stmt->returningList, + rewrite_timestamp_walker, (void *) ctx); rewrite = ctx->rewrite; /* - * INSERT INTO rel DEFAULT VALUES - * rewrite to: - * INSERT INTO rel VALUES (DEFAULT, '2009-..',...) + * INSERT INTO rel DEFAULT VALUES rewrite to: INSERT INTO rel VALUES + * (DEFAULT, '2009-..',...) */ if (i_stmt->selectStmt == NULL) { - List *values = NIL; - SelectStmt *selectStmt = makeNode(SelectStmt); + List *values = NIL; + SelectStmt *selectStmt = makeNode(SelectStmt); relcache = relcache_lookup(ctx); if (relcache == NULL) @@ -502,15 +516,17 @@ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) } else if (IsA(i_stmt->selectStmt, SelectStmt)) { - SelectStmt *selectStmt = (SelectStmt *) i_stmt->selectStmt; - ListCell *lc_row, *lc_val, *lc_col; + SelectStmt *selectStmt = (SelectStmt *) i_stmt->selectStmt; + ListCell *lc_row, + *lc_val, + *lc_col; /* * Rewrite `now()' call to timestamp literal. */ raw_expression_tree_walker( - (Node *) selectStmt, - rewrite_timestamp_walker, (void *) ctx); + (Node *) selectStmt, + rewrite_timestamp_walker, (void *) ctx); rewrite = ctx->rewrite; @@ -529,23 +545,18 @@ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) /* * INSERT INTO rel VALUES (...) * - * CREATE TABLE r1 ( - * i1 int, - * t1 timestamp default now(), - * i2 int, - * t2 timestamp default now(), - * ) + * CREATE TABLE r1 ( i1 int, t1 timestamp default now(), i2 int, + * t2 timestamp default now(), ) * - * INSERT INTO r1 VALUES (1, DEFAULT); - * rewrite to: - * INSERT INTO r1 VALUES (1, '20xx-xx-xx...', DEFAULT, '2..') + * INSERT INTO r1 VALUES (1, DEFAULT); rewrite to: INSERT INTO r1 + * VALUES (1, '20xx-xx-xx...', DEFAULT, '2..') */ - foreach (lc_row, selectStmt->valuesLists) + foreach(lc_row, selectStmt->valuesLists) { - List *values = lfirst(lc_row); + List *values = lfirst(lc_row); i = 0; - foreach (lc_val, values) + foreach(lc_val, values) { if (relcache->attr[i].use_timestamp == true && IsA(lfirst(lc_val), SetToDefault)) { @@ -580,21 +591,21 @@ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) /* * INSERT INTO rel(col1, col2) VALUES (val, val2) * - * if timestamp column is not given by column list - * add colname to column list and add timestamp to values list. + * if timestamp column is not given by column list add colname to + * column list and add timestamp to values list. */ int appended_columns = 0; - int *appended_columns_list; - ResTarget *col; + int *appended_columns_list; + ResTarget *col; - appended_columns_list = (int *)malloc(sizeof(int)*relcache->relnatts); + appended_columns_list = (int *) malloc(sizeof(int) * relcache->relnatts); for (i = 0; i < relcache->relnatts; i++) { if (relcache->attr[i].use_timestamp == false) continue; - foreach (lc_col, i_stmt->cols) + foreach(lc_col, i_stmt->cols) { col = lfirst(lc_col); @@ -602,7 +613,7 @@ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) break; } - /* If columns are not found in query, append these.*/ + /* If columns are not found in query, append these. */ if (lc_col == NULL) { rewrite = true; @@ -615,12 +626,12 @@ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) } } - foreach (lc_row, selectStmt->valuesLists) + foreach(lc_row, selectStmt->valuesLists) { - List *values = lfirst(lc_row); + List *values = lfirst(lc_row); /* replace DEFAULT in VALUES to literal */ - forboth (lc_col, i_stmt->cols, lc_val, values) + forboth(lc_col, i_stmt->cols, lc_val, values) { col = lfirst(lc_col); for (i = 0; i < relcache->relnatts; i++) @@ -661,40 +672,40 @@ rewrite_timestamp_insert(InsertStmt *i_stmt, TSRewriteContext *ctx) * rewrite UpdateStmt */ static bool -rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx) +rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext * ctx) { - TSRel *relcache = NULL; - ListCell *lc; - bool rewrite; + TSRel *relcache = NULL; + ListCell *lc; + bool rewrite; /* rewrite "update ... set col1 = now()" */ raw_expression_tree_walker( - (Node *) u_stmt->targetList, - rewrite_timestamp_walker, (void *) ctx); + (Node *) u_stmt->targetList, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( - (Node *) u_stmt->whereClause, - rewrite_timestamp_walker, (void *) ctx); + (Node *) u_stmt->whereClause, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( - (Node *) u_stmt->fromClause, - rewrite_timestamp_walker, (void *) ctx); + (Node *) u_stmt->fromClause, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( - (Node *) u_stmt->withClause, - rewrite_timestamp_walker, (void *) ctx); + (Node *) u_stmt->withClause, + rewrite_timestamp_walker, (void *) ctx); raw_expression_tree_walker( - (Node *) u_stmt->returningList, - rewrite_timestamp_walker, (void *) ctx); + (Node *) u_stmt->returningList, + rewrite_timestamp_walker, (void *) ctx); rewrite = ctx->rewrite; /* rewrite "update ... set col1 = default" */ - foreach (lc, u_stmt->targetList) + foreach(lc, u_stmt->targetList) { - ResTarget *res = (ResTarget *) lfirst(lc); - int i; + ResTarget *res = (ResTarget *) lfirst(lc); + int i; if (IsA(res->val, SetToDefault)) { @@ -711,7 +722,7 @@ rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx) if (ctx->rewrite_to_params) res->val = (Node *) makeTsExpr(ctx); else - res->val = (Node *)makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc); + res->val = (Node *) makeStringConstFromQuery(ctx->backend, relcache->attr[i].adsrc); rewrite = true; } break; @@ -729,14 +740,14 @@ rewrite_timestamp_update(UpdateStmt *u_stmt, TSRewriteContext *ctx) * returns query string as palloced string, or NULL if not to need rewrite. */ char * -rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, - bool rewrite_to_params, POOL_SENT_MESSAGE *message) +rewrite_timestamp(POOL_CONNECTION_POOL * backend, Node *node, + bool rewrite_to_params, POOL_SENT_MESSAGE * message) { - TSRewriteContext ctx; - Node *stmt; - bool rewrite = false; - char *timestamp; - char *rewrite_query; + TSRewriteContext ctx; + Node *stmt; + bool rewrite = false; + char *timestamp; + char *rewrite_query; if (node == NULL) return NULL; @@ -761,7 +772,7 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, stmt = ((PrepareStmt *) node)->query; ctx.rewrite_to_params = true; } - else if (IsA(node, CopyStmt) && ((CopyStmt *) node)->query != NULL) + else if (IsA(node, CopyStmt) &&((CopyStmt *) node)->query != NULL) stmt = ((CopyStmt *) node)->query; else stmt = node; @@ -770,33 +781,36 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, if (IsA(stmt, InsertStmt)) { InsertStmt *i_stmt = (InsertStmt *) stmt; + ctx.relname = make_table_name_from_rangevar(i_stmt->relation); rewrite = rewrite_timestamp_insert(i_stmt, &ctx); } else if (IsA(stmt, UpdateStmt)) { UpdateStmt *u_stmt = (UpdateStmt *) stmt; + ctx.relname = make_table_name_from_rangevar(u_stmt->relation); rewrite = rewrite_timestamp_update(u_stmt, &ctx); } else if (IsA(stmt, DeleteStmt)) { DeleteStmt *d_stmt = (DeleteStmt *) stmt; + raw_expression_tree_walker( - (Node *) d_stmt->usingClause, - rewrite_timestamp_walker, (void *) &ctx); + (Node *) d_stmt->usingClause, + rewrite_timestamp_walker, (void *) &ctx); raw_expression_tree_walker( - (Node *) d_stmt->whereClause, - rewrite_timestamp_walker, (void *) &ctx); + (Node *) d_stmt->whereClause, + rewrite_timestamp_walker, (void *) &ctx); raw_expression_tree_walker( - (Node *) d_stmt->returningList, - rewrite_timestamp_walker, (void *) &ctx); + (Node *) d_stmt->returningList, + rewrite_timestamp_walker, (void *) &ctx); raw_expression_tree_walker( - (Node *) d_stmt->withClause, - rewrite_timestamp_walker, (void *) &ctx); + (Node *) d_stmt->withClause, + rewrite_timestamp_walker, (void *) &ctx); rewrite = ctx.rewrite; } @@ -806,17 +820,18 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, /* rewrite params */ raw_expression_tree_walker( - (Node *) e_stmt->params, - rewrite_timestamp_walker, (void *) &ctx); + (Node *) e_stmt->params, + rewrite_timestamp_walker, (void *) &ctx); rewrite = ctx.rewrite; - /* add timestamp value into params list. - * The number of params is stored in message + /* + * add timestamp value into params list. The number of params is + * stored in message */ if (message) { - int i; + int i; for (i = 0; i < message->num_tsparams; i++) { @@ -828,8 +843,9 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, else ; - /* PREPARE, EXECUTE or Parse: - * save the number of parameters in the original query + /* + * PREPARE, EXECUTE or Parse: save the number of parameters in the + * original query */ if (message) message->query_context->num_original_params = ctx.num_params; @@ -838,18 +854,19 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, if (!rewrite) return NULL; - /* PREPARE or Parse: - * handle additinal parameters for timestamps + /* + * PREPARE or Parse: handle additinal parameters for timestamps */ if (ctx.rewrite_to_params && message) { - ListCell *lc; - int num = ctx.num_params + 1; + ListCell *lc; + int num = ctx.num_params + 1; /* renumber params */ - foreach (lc, ctx.params) + foreach(lc, ctx.params) { - ParamRef *param = (ParamRef *) lfirst(lc); + ParamRef *param = (ParamRef *) lfirst(lc); + param->number = num++; } @@ -859,12 +876,12 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, /* add type names of timestamptz into argtypes */ if (IsA(node, PrepareStmt)) { - int i; - PrepareStmt *p_stmt = (PrepareStmt *) node; + int i; + PrepareStmt *p_stmt = (PrepareStmt *) node; for (i = 0; i < message->num_tsparams; i++) p_stmt->argtypes = - lappend(p_stmt->argtypes, SystemTypeName("timestamptz")); + lappend(p_stmt->argtypes, SystemTypeName("timestamptz")); } } else @@ -889,26 +906,26 @@ rewrite_timestamp(POOL_CONNECTION_POOL *backend, Node *node, * rewrite Bind message to add parameter values */ char * -bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, - POOL_SENT_MESSAGE *message, +bind_rewrite_timestamp(POOL_CONNECTION_POOL * backend, + POOL_SENT_MESSAGE * message, const char *orig_msg, int *len) { - int16 tmp2, - num_params, - num_formats; - int32 tmp4; - int i, - ts_len, - copy_len, - num_org_params; - const char *copy_from; - char *ts, - *copy_to, - *new_msg; + int16 tmp2, + num_params, + num_formats; + int32 tmp4; + int i, + ts_len, + copy_len, + num_org_params; + const char *copy_from; + char *ts, + *copy_to, + *new_msg; #ifdef TIMESTAMPDEBUG fprintf(stderr, "message length:%d\n", *len); - for(i=0;i<*len;i++) + for (i = 0; i < *len; i++) { fprintf(stderr, "%02x ", orig_msg[i]); } @@ -918,7 +935,7 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, if (ts == NULL) { ereport(WARNING, - (errmsg("bind rewrite timestamp failed, unable to get current timestamp"))); + (errmsg("bind rewrite timestamp failed, unable to get current timestamp"))); return NULL; } @@ -934,12 +951,14 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, /* portal_name */ copy_len = strlen(copy_from) + 1; memcpy(copy_to, copy_from, copy_len); - copy_to += copy_len; copy_from += copy_len; + copy_to += copy_len; + copy_from += copy_len; /* stmt_name */ copy_len = strlen(copy_from) + 1; memcpy(copy_to, copy_from, copy_len); - copy_to += copy_len; copy_from += copy_len; + copy_to += copy_len; + copy_from += copy_len; /* format code */ memcpy(&tmp2, copy_from, sizeof(int16)); @@ -948,7 +967,10 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, if (num_formats >= 1) { - /* this means the specified format code is applied all original parameters */ + /* + * this means the specified format code is applied all original + * parameters + */ if (num_formats == 1) { *len += (num_org_params - 1) * sizeof(int16); @@ -962,12 +984,14 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, tmp2 = htons(tmp2); memcpy(copy_to, &tmp2, copy_len); /* copy number of format codes */ - copy_to += copy_len; copy_from += copy_len; + copy_to += copy_len; + copy_from += copy_len; copy_len = num_formats * sizeof(int16); - memcpy(copy_to, copy_from, copy_len); /* copy format codes */ - copy_to += copy_len; copy_from += copy_len; + memcpy(copy_to, copy_from, copy_len); /* copy format codes */ + copy_to += copy_len; + copy_from += copy_len; if (num_formats >= 1) { @@ -989,7 +1013,8 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, num_params = ntohs(tmp2); tmp2 = htons(num_params + message->num_tsparams); memcpy(copy_to, &tmp2, sizeof(int16)); - copy_to += copy_len; copy_from += copy_len; + copy_to += copy_len; + copy_from += copy_len; /* params */ copy_len = 0; @@ -999,8 +1024,9 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, tmp4 = ntohl(tmp4); /* param length */ copy_len += sizeof(int32); - /* If param length is -1, it indicates that the value is NULL - * and we don't have value slot. So we don't add up copy_len. + /* + * If param length is -1, it indicates that the value is NULL and we + * don't have value slot. So we don't add up copy_len. */ if (tmp4 > 0) { @@ -1008,7 +1034,8 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, } } memcpy(copy_to, copy_from, copy_len); - copy_to += copy_len; copy_from += copy_len; + copy_to += copy_len; + copy_from += copy_len; tmp4 = htonl(ts_len); for (i = 0; i < message->num_tsparams; i++) @@ -1029,13 +1056,14 @@ bind_rewrite_timestamp(POOL_CONNECTION_POOL *backend, } /* make A_Const of T_String from "SELECT <expression>"*/ -static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *expression) +static A_Const * +makeStringConstFromQuery(POOL_CONNECTION_POOL * backend, char *expression) { - A_Const *con; + A_Const *con; POOL_SELECT_RESULT *res; - char query[1024]; - int len; - char *str; + char query[1024]; + int len; + char *str; snprintf(query, sizeof(query), "SELECT %s", expression); do_query(MASTER(backend), query, &res, MAJOR(backend)); @@ -1060,9 +1088,9 @@ static A_Const *makeStringConstFromQuery(POOL_CONNECTION_POOL *backend, char *ex static TypeCast * makeTypeCastFromSvfOp(SQLValueFunctionOp op) { - TypeName *typename; - Node *n; - int location; + TypeName *typename; + Node *n; + int location; switch (op) { @@ -1150,9 +1178,10 @@ raw_expression_tree_walker(Node *node, return false; /* Guard against stack overflow due to overly complex expressions */ + /* - check_stack_depth(); - */ + * check_stack_depth(); + */ switch (nodeTag(node)) { @@ -1554,13 +1583,13 @@ raw_expression_tree_walker(Node *node, case T_CommonTableExpr: return walker(((CommonTableExpr *) node)->ctequery, context); default: + /* - elog(ERROR, "unrecognized node type: %d", - (int) nodeTag(node)); - */ + * elog(ERROR, "unrecognized node type: %d", (int) nodeTag(node)); + */ break; } return false; } -/* from nodeFuncs.c end */ +/* from nodeFuncs.c end */ diff --git a/src/sql/pgpool-recovery/pgpool-recovery.c b/src/sql/pgpool-recovery/pgpool-recovery.c index e2120b812..0890fc3ce 100644 --- a/src/sql/pgpool-recovery/pgpool-recovery.c +++ b/src/sql/pgpool-recovery/pgpool-recovery.c @@ -31,7 +31,7 @@ #include "utils/builtins.h" /* PostgreSQL 8.4 needs this for textout */ #include "utils/guc.h" #if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 90300) -#include "access/htup_details.h" /* PostgreSQL 9.3 or later needs this */ +#include "access/htup_details.h" /* PostgreSQL 9.3 or later needs this */ #endif #define REMOTE_START_FILE "pgpool_remote_start" @@ -55,20 +55,20 @@ extern Datum pgpool_switch_xlog(PG_FUNCTION_ARGS); static char recovery_script[1024]; static char command_text[1024]; -static Oid get_function_oid(const char *funcname, const char *argtype, const char *nspname); -char *Log_line_prefix = NULL; +static Oid get_function_oid(const char *funcname, const char *argtype, const char *nspname); +char *Log_line_prefix = NULL; Datum pgpool_recovery(PG_FUNCTION_ARGS) { - int r; - char *script = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(0)))); - - char *remote_host = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(1)))); - char *remote_data_directory = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(2)))); + int r; + char *script = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(0)))); + + char *remote_host = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(1)))); + char *remote_data_directory = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(2)))); if (!superuser()) #ifdef ERRCODE_INSUFFICIENT_PRIVILEGE @@ -81,17 +81,19 @@ pgpool_recovery(PG_FUNCTION_ARGS) if (PG_NARGS() >= 5) /* Pgpool-II 4.0 or later */ { - char *remote_port = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(3)))); - int recovery_node = PG_GETARG_INT32(4); + char *remote_port = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(3)))); + int recovery_node = PG_GETARG_INT32(4); + snprintf(recovery_script, sizeof(recovery_script), "\"%s/%s\" \"%s\" \"%s\" \"%s\" \"%s\" %d", DataDir, script, DataDir, remote_host, remote_data_directory, remote_port, recovery_node); } - else if (PG_NARGS() >= 4) /* Pgpool-II 3.4 - 3.7 */ + else if (PG_NARGS() >= 4) /* Pgpool-II 3.4 - 3.7 */ { - char *remote_port = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(3)))); + char *remote_port = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(3)))); + snprintf(recovery_script, sizeof(recovery_script), "\"%s/%s\" \"%s\" \"%s\" \"%s\" \"%s\"", DataDir, script, DataDir, remote_host, remote_data_directory, remote_port); @@ -117,11 +119,12 @@ pgpool_recovery(PG_FUNCTION_ARGS) Datum pgpool_remote_start(PG_FUNCTION_ARGS) { - int r; - char *remote_host = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(0)))); - char *remote_data_directory = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(1)))); + int r; + char *remote_host = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(0)))); + char *remote_data_directory = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(1)))); + if (!superuser()) #ifdef ERRCODE_INSUFFICIENT_PRIVILEGE ereport(ERROR, @@ -148,13 +151,13 @@ pgpool_remote_start(PG_FUNCTION_ARGS) Datum pgpool_pgctl(PG_FUNCTION_ARGS) { - int r; - char *action = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(0)))); - char *stop_mode = DatumGetCString(DirectFunctionCall1(textout, - PointerGetDatum(PG_GETARG_TEXT_P(1)))); - char *pg_ctl; - char *data_directory; + int r; + char *action = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(0)))); + char *stop_mode = DatumGetCString(DirectFunctionCall1(textout, + PointerGetDatum(PG_GETARG_TEXT_P(1)))); + char *pg_ctl; + char *data_directory; if (!superuser()) #ifdef ERRCODE_INSUFFICIENT_PRIVILEGE @@ -166,8 +169,8 @@ pgpool_pgctl(PG_FUNCTION_ARGS) #endif #if defined(PG_VERSION_NUM) && (PG_VERSION_NUM >= 90600) - pg_ctl = GetConfigOptionByName("pgpool.pg_ctl", NULL,false); - data_directory = GetConfigOptionByName("data_directory", NULL,false); + pg_ctl = GetConfigOptionByName("pgpool.pg_ctl", NULL, false); + data_directory = GetConfigOptionByName("data_directory", NULL, false); #else pg_ctl = GetConfigOptionByName("pgpool.pg_ctl", NULL); data_directory = GetConfigOptionByName("data_directory", NULL); @@ -179,7 +182,9 @@ pgpool_pgctl(PG_FUNCTION_ARGS) "%s %s -D %s -m %s 2>/dev/null 1>/dev/null < /dev/null &", pg_ctl, action, data_directory, stop_mode); - } else { + } + else + { snprintf(command_text, sizeof(command_text), "%s %s -D %s 2>/dev/null 1>/dev/null < /dev/null &", pg_ctl, action, data_directory); @@ -205,24 +210,25 @@ pgpool_pgctl(PG_FUNCTION_ARGS) Datum pgpool_switch_xlog(PG_FUNCTION_ARGS) { - char *archive_dir; - char *filename; - char path[MAXPGPATH]; + char *archive_dir; + char *filename; + char path[MAXPGPATH]; struct stat fst; - Datum location; - text *filename_t; - text *result; - Oid switch_xlog_oid; - Oid xlogfile_name_oid; + Datum location; + text *filename_t; + text *result; + Oid switch_xlog_oid; + Oid xlogfile_name_oid; #if !defined(PG_VERSION_NUM) || (PG_VERSION_NUM < 90400) - char* pg_xlogfile_name_arg_type = "text"; + char *pg_xlogfile_name_arg_type = "text"; #else - /* - * The argument data type of PG's pg_xlogfile_name() function - * has been changed from text to pg_lsn since PostgreSQL 9.4 + + /* + * The argument data type of PG's pg_xlogfile_name() function has been + * changed from text to pg_lsn since PostgreSQL 9.4 */ - char* pg_xlogfile_name_arg_type = "pg_lsn"; + char *pg_xlogfile_name_arg_type = "pg_lsn"; #endif @@ -232,10 +238,10 @@ pgpool_switch_xlog(PG_FUNCTION_ARGS) if (stat(archive_dir, &fst) < 0) #ifdef ERRCODE_INSUFFICIENT_PRIVILEGE ereport(ERROR, - (errcode_for_file_access(), - errmsg("could not stat file \"%s\": %m", archive_dir))); + (errcode_for_file_access(), + errmsg("could not stat file \"%s\": %m", archive_dir))); #else - elog(ERROR, "could not stat file \"%s\"", archive_dir); + elog(ERROR, "could not stat file \"%s\"", archive_dir); #endif switch_xlog_oid = get_function_oid("pg_switch_xlog", NULL, "pg_catalog"); @@ -259,15 +265,15 @@ pgpool_switch_xlog(PG_FUNCTION_ARGS) snprintf(path, MAXPGPATH, "%s/%s", archive_dir, filename); elog(LOG, "pgpool_switch_xlog: waiting for \"%s\"", path); - while(stat(path, &fst) != 0 || fst.st_size == 0 || - fst.st_size % (1024 * 1024) != 0) + while (stat(path, &fst) != 0 || fst.st_size == 0 || + fst.st_size % (1024 * 1024) != 0) { CHECK_FOR_INTERRUPTS(); sleep(1); } - result = DatumGetTextP(DirectFunctionCall1(textin, - CStringGetDatum(path))); + result = DatumGetTextP(DirectFunctionCall1(textin, + CStringGetDatum(path))); PG_RETURN_TEXT_P(result); } @@ -276,12 +282,12 @@ static Oid get_function_oid(const char *funcname, const char *argtype, const char *nspname) { #ifndef PROCNAMENSP - Oid typid; - Oid nspid; - Oid funcid; - Oid oids[1]; - oidvector *oid_v; - HeapTuple tup; + Oid typid; + Oid nspid; + Oid funcid; + Oid oids[1]; + oidvector *oid_v; + HeapTuple tup; if (argtype) { @@ -298,9 +304,12 @@ get_function_oid(const char *funcname, const char *argtype, const char *nspname) #if !defined(PG_VERSION_NUM) || (PG_VERSION_NUM < 90300) nspid = LookupExplicitNamespace(nspname); #else - /* LookupExplicitNamespace() of PostgreSQL 9.3 or later, has third - * argument "missing_ok" which suppresses ERROR exception, but - * returns invlaid_oid. See include/catalog/namespace.h */ + + /* + * LookupExplicitNamespace() of PostgreSQL 9.3 or later, has third + * argument "missing_ok" which suppresses ERROR exception, but returns + * invlaid_oid. See include/catalog/namespace.h + */ nspid = LookupExplicitNamespace(nspname, false); #endif elog(DEBUG1, "get_function_oid: oid of \"%s\": %d", nspname, nspid); @@ -321,4 +330,3 @@ get_function_oid(const char *funcname, const char *argtype, const char *nspname) #endif return 0; } - diff --git a/src/sql/pgpool-regclass/pgpool-regclass.c b/src/sql/pgpool-regclass/pgpool-regclass.c index 2b9e40689..5d9d024fb 100644 --- a/src/sql/pgpool-regclass/pgpool-regclass.c +++ b/src/sql/pgpool-regclass/pgpool-regclass.c @@ -43,25 +43,23 @@ PG_FUNCTION_INFO_V1(pgpool_regclass); extern Datum pgpool_regclass(PG_FUNCTION_ARGS); -static List * -MystringToQualifiedNameList(const char *string); +static List *MystringToQualifiedNameList(const char *string); -static RangeVar * -MymakeRangeVarFromNameList(List *names); +static RangeVar *MymakeRangeVarFromNameList(List *names); -extern Oid MyDatabaseId; +extern Oid MyDatabaseId; #if !defined(PG_VERSION_NUM) || (PG_VERSION_NUM < 90100) static Oid -get_namespace_oid(const char *nspname, bool missing_ok); + get_namespace_oid(const char *nspname, bool missing_ok); #endif Datum pgpool_regclass(PG_FUNCTION_ARGS) { - char *pro_name_or_oid = PG_GETARG_CSTRING(0); - Oid result; - List *names; + char *pro_name_or_oid = PG_GETARG_CSTRING(0); + Oid result; + List *names; RangeVar *rel; names = MystringToQualifiedNameList(pro_name_or_oid); @@ -73,10 +71,9 @@ pgpool_regclass(PG_FUNCTION_ARGS) PG_RETURN_OID(InvalidOid); /* - * Check to see if cross-database reference is used. - * This is to be done in RangeVarGetRelid(). The reason - * we do this here is, to avoid raising an error - * in RangeVarGetRelid(). + * Check to see if cross-database reference is used. This is to be done in + * RangeVarGetRelid(). The reason we do this here is, to avoid raising an + * error in RangeVarGetRelid(). */ if (rel->catalogname) { @@ -85,10 +82,9 @@ pgpool_regclass(PG_FUNCTION_ARGS) } /* - * Check to see if schema exists. - * This is to be done in RangeVarGetRelid(). The reason - * we do this here is, to avoid raising an error - * in RangeVarGetRelid(). + * Check to see if schema exists. This is to be done in + * RangeVarGetRelid(). The reason we do this here is, to avoid raising an + * error in RangeVarGetRelid(). */ if (rel->schemaname) { @@ -98,9 +94,12 @@ pgpool_regclass(PG_FUNCTION_ARGS) #if !defined(PG_VERSION_NUM) || (PG_VERSION_NUM < 90200) result = RangeVarGetRelid(rel, true); #else - /* RangeVarGetRelid() of PostgreSQL 9.2 or later, has third - * argument "missing_ok" which suppresses ERROR exception, but - * returns invlaid_oid. See include/catalog/namespace.h */ + + /* + * RangeVarGetRelid() of PostgreSQL 9.2 or later, has third argument + * "missing_ok" which suppresses ERROR exception, but returns invlaid_oid. + * See include/catalog/namespace.h + */ result = RangeVarGetRelid(rel, true, true); #endif PG_RETURN_OID(result); @@ -197,9 +196,9 @@ get_namespace_oid(const char *nspname, bool missing_ok) oid = GetSysCacheOid(NAMESPACENAME, CStringGetDatum(nspname), 0, 0, 0); if (!OidIsValid(oid) && !missing_ok) - ereport(ERROR, - (errcode(ERRCODE_UNDEFINED_SCHEMA), - errmsg("schema \"%s\" does not exist", nspname))); + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_SCHEMA), + errmsg("schema \"%s\" does not exist", nspname))); return oid; } diff --git a/src/sql/pgpool_adm/pgpool_adm.c b/src/sql/pgpool_adm/pgpool_adm.c index c58ee0fe4..418f096ca 100644 --- a/src/sql/pgpool_adm/pgpool_adm.c +++ b/src/sql/pgpool_adm/pgpool_adm.c @@ -19,7 +19,7 @@ #include "nodes/pg_list.h" #include "utils/timestamp.h" -/* +/* * PostgreSQL 9.3 or later requires htup_details.h to get the definition of * heap_form_tuple */ @@ -36,23 +36,24 @@ #include "pgpool_adm.h" -static PCPConnInfo *connect_to_server(char* host, int port, char* user, char* pass); -static PCPConnInfo *connect_to_server_from_foreign_server(char * name); +static PCPConnInfo * connect_to_server(char *host, int port, char *user, char *pass); +static PCPConnInfo * connect_to_server_from_foreign_server(char *name); /** * Wrapper around pcp_connect * pcp_conninfo: pcpConninfo structure having pcp connection properties */ -static PCPConnInfo* -connect_to_server(char* host, int port, char* user, char* pass) +static PCPConnInfo * +connect_to_server(char *host, int port, char *user, char *pass) { - PCPConnInfo* pcpConnInfo; + PCPConnInfo *pcpConnInfo; + pcpConnInfo = pcp_connect(host, port, user, pass, NULL); if (PCPConnectionStatus(pcpConnInfo) != PCP_CONNECTION_OK) - ereport(ERROR,(0, - errmsg("connection to PCP server failed."), - errdetail("%s\n",pcp_get_last_error(pcpConnInfo)?pcp_get_last_error(pcpConnInfo):"unknown reason"))); + ereport(ERROR, (0, + errmsg("connection to PCP server failed."), + errdetail("%s\n", pcp_get_last_error(pcpConnInfo) ? pcp_get_last_error(pcpConnInfo) : "unknown reason"))); return pcpConnInfo; } @@ -61,25 +62,29 @@ connect_to_server(char* host, int port, char* user, char* pass) * Returns a pcpConninfo structure filled from a foreign server * name: the name of the foreign server */ -static PCPConnInfo* -connect_to_server_from_foreign_server(char * name) +static PCPConnInfo * +connect_to_server_from_foreign_server(char *name) { - Oid userid = GetUserId(); - char* user = NULL; - char* host = NULL; - int port = 9898; - char* pass = NULL; - /* raise an error if given foreign server doesn't exists */ - ForeignServer * foreign_server = GetForeignServerByName(name, false); - UserMapping * user_mapping; - ListCell * cell; + Oid userid = GetUserId(); + char *user = NULL; + char *host = NULL; + int port = 9898; + char *pass = NULL; - /* raise an error if the current user isn't mapped with the given foreign server */ + /* raise an error if given foreign server doesn't exists */ + ForeignServer *foreign_server = GetForeignServerByName(name, false); + UserMapping *user_mapping; + ListCell *cell; + + /* + * raise an error if the current user isn't mapped with the given foreign + * server + */ user_mapping = GetUserMapping(userid, foreign_server->serverid); foreach(cell, foreign_server->options) { - DefElem * def = lfirst(cell); + DefElem *def = lfirst(cell); if (strcmp(def->defname, "host") == 0) { @@ -93,7 +98,7 @@ connect_to_server_from_foreign_server(char * name) foreach(cell, user_mapping->options) { - DefElem * def = lfirst(cell); + DefElem *def = lfirst(cell); if (strcmp(def->defname, "user") == 0) { @@ -105,7 +110,7 @@ connect_to_server_from_foreign_server(char * name) } } - return connect_to_server(host,port,user,pass); + return connect_to_server(host, port, user, pass); } /** @@ -118,31 +123,33 @@ connect_to_server_from_foreign_server(char * name) Datum _pcp_node_info(PG_FUNCTION_ARGS) { - int16 nodeID = PG_GETARG_INT16(0); - char *host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(1)); + int16 nodeID = PG_GETARG_INT16(0); + char *host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(1)); - PCPConnInfo* pcpConnInfo; - PCPResultInfo* pcpResInfo; + PCPConnInfo *pcpConnInfo; + PCPResultInfo *pcpResInfo; - BackendInfo * backend_info = NULL; - Datum values[7]; /* values to build the returned tuple from */ - bool nulls[] = {false, false, false, false, false, false, false}; - TupleDesc tupledesc; - HeapTuple tuple; - struct tm tm; - char datebuf[20]; + BackendInfo *backend_info = NULL; + Datum values[7]; /* values to build the returned tuple from */ + bool nulls[] = {false, false, false, false, false, false, false}; + TupleDesc tupledesc; + HeapTuple tuple; + struct tm tm; + char datebuf[20]; if (nodeID < 0 || nodeID >= MAX_NUM_BACKENDS) ereport(ERROR, (0, errmsg("NodeID is out of range."))); if (PG_NARGS() == 5) { - char *user, *pass; - int port; + char *user, + *pass; + int port; + port = PG_GETARG_INT16(2); user = text_to_cstring(PG_GETARG_TEXT_PP(3)); pass = text_to_cstring(PG_GETARG_TEXT_PP(4)); - pcpConnInfo = connect_to_server(host_or_srv,port,user,pass); + pcpConnInfo = connect_to_server(host_or_srv, port, user, pass); } else if (PG_NARGS() == 2) { @@ -153,15 +160,16 @@ _pcp_node_info(PG_FUNCTION_ARGS) ereport(ERROR, (0, errmsg("Wrong number of argument."))); } - pcpResInfo = pcp_node_info(pcpConnInfo,nodeID); + pcpResInfo = pcp_node_info(pcpConnInfo, nodeID); if (pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) { - char *error = pcp_get_last_error(pcpConnInfo)? pstrdup(pcp_get_last_error(pcpConnInfo)):NULL; + char *error = pcp_get_last_error(pcpConnInfo) ? pstrdup(pcp_get_last_error(pcpConnInfo)) : NULL; + pcp_disconnect(pcpConnInfo); pcp_free_connection(pcpConnInfo); - ereport(ERROR,(0, - errmsg("failed to get node information"), - errdetail("%s\n",error?error:"unknown reason"))); + ereport(ERROR, (0, + errmsg("failed to get node information"), + errdetail("%s\n", error ? error : "unknown reason"))); } /** @@ -177,7 +185,7 @@ _pcp_node_info(PG_FUNCTION_ARGS) TupleDescInitEntry(tupledesc, (AttrNumber) 7, "last_status_change", TIMESTAMPOID, -1, 0); tupledesc = BlessTupleDesc(tupledesc); - backend_info = (BackendInfo *) pcp_get_binary_data(pcpResInfo,0); + backend_info = (BackendInfo *) pcp_get_binary_data(pcpResInfo, 0); /* set values */ values[0] = CStringGetTextDatum(backend_info->backend_hostname); @@ -200,11 +208,11 @@ _pcp_node_info(PG_FUNCTION_ARGS) break; } nulls[2] = false; - values[3] = Float8GetDatum(backend_info->backend_weight/RAND_MAX); + values[3] = Float8GetDatum(backend_info->backend_weight / RAND_MAX); nulls[3] = false; nulls[4] = false; - values[4] = backend_info->role == ROLE_PRIMARY?CStringGetTextDatum("Primary"):CStringGetTextDatum("Standby"); + values[4] = backend_info->role == ROLE_PRIMARY ? CStringGetTextDatum("Primary") : CStringGetTextDatum("Standby"); nulls[5] = false; values[5] = Int64GetDatum(backend_info->standby_delay); @@ -239,18 +247,18 @@ _pcp_pool_status(PG_FUNCTION_ARGS) { MemoryContext oldcontext; FuncCallContext *funcctx; - int32 nrows; - int32 call_cntr; - int32 max_calls; + int32 nrows; + int32 call_cntr; + int32 max_calls; AttInMetadata *attinmeta; - PCPConnInfo* pcpConnInfo; - PCPResultInfo* pcpResInfo; + PCPConnInfo *pcpConnInfo; + PCPResultInfo *pcpResInfo; /* stuff done only on the first call of the function */ if (SRF_IS_FIRSTCALL()) { - TupleDesc tupdesc; - char * host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(0)); + TupleDesc tupdesc; + char *host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(0)); /* create a function context for cross-call persistence */ funcctx = SRF_FIRSTCALL_INIT(); @@ -260,12 +268,14 @@ _pcp_pool_status(PG_FUNCTION_ARGS) if (PG_NARGS() == 4) { - char *user, *pass; - int port; + char *user, + *pass; + int port; + port = PG_GETARG_INT16(1); user = text_to_cstring(PG_GETARG_TEXT_PP(2)); pass = text_to_cstring(PG_GETARG_TEXT_PP(3)); - pcpConnInfo = connect_to_server(host_or_srv,port,user,pass); + pcpConnInfo = connect_to_server(host_or_srv, port, user, pass); } else if (PG_NARGS() == 1) @@ -281,14 +291,15 @@ _pcp_pool_status(PG_FUNCTION_ARGS) pcpResInfo = pcp_pool_status(pcpConnInfo); if (pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) { - char *error = pcp_get_last_error(pcpConnInfo)? pstrdup(pcp_get_last_error(pcpConnInfo)):NULL; + char *error = pcp_get_last_error(pcpConnInfo) ? pstrdup(pcp_get_last_error(pcpConnInfo)) : NULL; + pcp_disconnect(pcpConnInfo); pcp_free_connection(pcpConnInfo); MemoryContextSwitchTo(oldcontext); - ereport(ERROR,(0, - errmsg("failed to get pool status"), - errdetail("%s\n",error?error:"unknown reason"))); + ereport(ERROR, (0, + errmsg("failed to get pool status"), + errdetail("%s\n", error ? error : "unknown reason"))); } nrows = pcp_result_slot_count(pcpResInfo); @@ -330,16 +341,16 @@ _pcp_pool_status(PG_FUNCTION_ARGS) call_cntr = funcctx->call_cntr; max_calls = funcctx->max_calls; - pcpConnInfo = (PCPConnInfo*) funcctx->user_fctx; - pcpResInfo = (PCPResultInfo*) pcpConnInfo->pcpResInfo; + pcpConnInfo = (PCPConnInfo *) funcctx->user_fctx; + pcpResInfo = (PCPResultInfo *) pcpConnInfo->pcpResInfo; attinmeta = funcctx->attinmeta; if (call_cntr < max_calls) /* executed while there is more left to send */ { - char * values[3]; - HeapTuple tuple; - Datum result; - POOL_REPORT_CONFIG *status = (POOL_REPORT_CONFIG *)pcp_get_binary_data(pcpResInfo, call_cntr); + char *values[3]; + HeapTuple tuple; + Datum result; + POOL_REPORT_CONFIG *status = (POOL_REPORT_CONFIG *) pcp_get_binary_data(pcpResInfo, call_cntr); values[0] = pstrdup(status->name); values[1] = pstrdup(status->value); @@ -371,20 +382,22 @@ _pcp_pool_status(PG_FUNCTION_ARGS) Datum _pcp_node_count(PG_FUNCTION_ARGS) { - char * host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(0)); - int16 node_count = 0; + char *host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(0)); + int16 node_count = 0; - PCPConnInfo* pcpConnInfo; - PCPResultInfo* pcpResInfo; + PCPConnInfo *pcpConnInfo; + PCPResultInfo *pcpResInfo; if (PG_NARGS() == 4) { - char *user, *pass; - int port; + char *user, + *pass; + int port; + port = PG_GETARG_INT16(1); user = text_to_cstring(PG_GETARG_TEXT_PP(2)); pass = text_to_cstring(PG_GETARG_TEXT_PP(3)); - pcpConnInfo = connect_to_server(host_or_srv,port,user,pass); + pcpConnInfo = connect_to_server(host_or_srv, port, user, pass); } else if (PG_NARGS() == 1) { @@ -399,12 +412,13 @@ _pcp_node_count(PG_FUNCTION_ARGS) if (pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) { - char *error = pcp_get_last_error(pcpConnInfo)? pstrdup(pcp_get_last_error(pcpConnInfo)):NULL; + char *error = pcp_get_last_error(pcpConnInfo) ? pstrdup(pcp_get_last_error(pcpConnInfo)) : NULL; + pcp_disconnect(pcpConnInfo); pcp_free_connection(pcpConnInfo); - ereport(ERROR,(0, - errmsg("failed to get node count"), - errdetail("%s\n",error?error:"unknown reason"))); + ereport(ERROR, (0, + errmsg("failed to get node count"), + errdetail("%s\n", error ? error : "unknown reason"))); } node_count = pcp_get_int_data(pcpResInfo, 0); @@ -425,23 +439,25 @@ _pcp_node_count(PG_FUNCTION_ARGS) Datum _pcp_attach_node(PG_FUNCTION_ARGS) { - int16 nodeID = PG_GETARG_INT16(0); - char * host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(1)); + int16 nodeID = PG_GETARG_INT16(0); + char *host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(1)); - PCPConnInfo* pcpConnInfo; - PCPResultInfo* pcpResInfo; + PCPConnInfo *pcpConnInfo; + PCPResultInfo *pcpResInfo; if (nodeID < 0 || nodeID >= MAX_NUM_BACKENDS) ereport(ERROR, (0, errmsg("NodeID is out of range."))); if (PG_NARGS() == 5) { - char *user, *pass; - int port; + char *user, + *pass; + int port; + port = PG_GETARG_INT16(2); user = text_to_cstring(PG_GETARG_TEXT_PP(3)); pass = text_to_cstring(PG_GETARG_TEXT_PP(4)); - pcpConnInfo = connect_to_server(host_or_srv,port,user,pass); + pcpConnInfo = connect_to_server(host_or_srv, port, user, pass); } else if (PG_NARGS() == 2) { @@ -452,16 +468,17 @@ _pcp_attach_node(PG_FUNCTION_ARGS) ereport(ERROR, (0, errmsg("Wrong number of argument."))); } - pcpResInfo = pcp_attach_node(pcpConnInfo,nodeID); + pcpResInfo = pcp_attach_node(pcpConnInfo, nodeID); if (pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) { - char *error = pcp_get_last_error(pcpConnInfo)? pstrdup(pcp_get_last_error(pcpConnInfo)):NULL; + char *error = pcp_get_last_error(pcpConnInfo) ? pstrdup(pcp_get_last_error(pcpConnInfo)) : NULL; + pcp_disconnect(pcpConnInfo); pcp_free_connection(pcpConnInfo); - ereport(ERROR,(0, - errmsg("failed to attach node"), - errdetail("%s\n",error?error:"unknown reason"))); + ereport(ERROR, (0, + errmsg("failed to attach node"), + errdetail("%s\n", error ? error : "unknown reason"))); } pcp_disconnect(pcpConnInfo); @@ -482,24 +499,26 @@ _pcp_attach_node(PG_FUNCTION_ARGS) Datum _pcp_detach_node(PG_FUNCTION_ARGS) { - int16 nodeID = PG_GETARG_INT16(0); - bool gracefully = PG_GETARG_BOOL(1); - char * host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(2)); + int16 nodeID = PG_GETARG_INT16(0); + bool gracefully = PG_GETARG_BOOL(1); + char *host_or_srv = text_to_cstring(PG_GETARG_TEXT_PP(2)); - PCPConnInfo* pcpConnInfo; - PCPResultInfo* pcpResInfo; + PCPConnInfo *pcpConnInfo; + PCPResultInfo *pcpResInfo; if (nodeID < 0 || nodeID >= MAX_NUM_BACKENDS) ereport(ERROR, (0, errmsg("NodeID is out of range."))); if (PG_NARGS() == 6) { - char *user, *pass; - int port; + char *user, + *pass; + int port; + port = PG_GETARG_INT16(3); user = text_to_cstring(PG_GETARG_TEXT_PP(4)); pass = text_to_cstring(PG_GETARG_TEXT_PP(5)); - pcpConnInfo = connect_to_server(host_or_srv,port,user,pass); + pcpConnInfo = connect_to_server(host_or_srv, port, user, pass); } else if (PG_NARGS() == 3) { @@ -512,21 +531,22 @@ _pcp_detach_node(PG_FUNCTION_ARGS) if (gracefully) { - pcpResInfo = pcp_detach_node_gracefully(pcpConnInfo,nodeID); + pcpResInfo = pcp_detach_node_gracefully(pcpConnInfo, nodeID); } else { - pcpResInfo = pcp_detach_node(pcpConnInfo,nodeID); + pcpResInfo = pcp_detach_node(pcpConnInfo, nodeID); } if (pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) { - char *error = pcp_get_last_error(pcpConnInfo)? pstrdup(pcp_get_last_error(pcpConnInfo)):NULL; + char *error = pcp_get_last_error(pcpConnInfo) ? pstrdup(pcp_get_last_error(pcpConnInfo)) : NULL; + pcp_disconnect(pcpConnInfo); pcp_free_connection(pcpConnInfo); - ereport(ERROR,(0, - errmsg("failed to detach node"), - errdetail("%s\n",error?error:"unknown reason"))); + ereport(ERROR, (0, + errmsg("failed to detach node"), + errdetail("%s\n", error ? error : "unknown reason"))); } pcp_disconnect(pcpConnInfo); diff --git a/src/sql/pgpool_adm/pgpool_adm.h b/src/sql/pgpool_adm/pgpool_adm.h index efc1e0cb3..7dbbd9ec5 100644 --- a/src/sql/pgpool_adm/pgpool_adm.h +++ b/src/sql/pgpool_adm/pgpool_adm.h @@ -19,11 +19,11 @@ PG_MODULE_MAGIC; -Datum _pcp_node_info(PG_FUNCTION_ARGS); -Datum _pcp_pool_status(PG_FUNCTION_ARGS); -Datum _pcp_node_count(PG_FUNCTION_ARGS); -Datum _pcp_attach_node(PG_FUNCTION_ARGS); -Datum _pcp_detach_node(PG_FUNCTION_ARGS); +Datum _pcp_node_info(PG_FUNCTION_ARGS); +Datum _pcp_pool_status(PG_FUNCTION_ARGS); +Datum _pcp_node_count(PG_FUNCTION_ARGS); +Datum _pcp_attach_node(PG_FUNCTION_ARGS); +Datum _pcp_detach_node(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(_pcp_node_info); PG_FUNCTION_INFO_V1(_pcp_pool_status); diff --git a/src/streaming_replication/pool_worker_child.c b/src/streaming_replication/pool_worker_child.c index 58e95adad..bbb9f269b 100644 --- a/src/streaming_replication/pool_worker_child.c +++ b/src/streaming_replication/pool_worker_child.c @@ -61,8 +61,8 @@ #include "auth/pool_hba.h" #include "utils/pool_stream.h" -char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ -static POOL_CONNECTION_POOL_SLOT *slots[MAX_NUM_BACKENDS]; +char remote_ps_data[NI_MAXHOST]; /* used for set_ps_display */ +static POOL_CONNECTION_POOL_SLOT * slots[MAX_NUM_BACKENDS]; static volatile sig_atomic_t reload_config_request = 0; static volatile sig_atomic_t restart_request = 0; @@ -94,13 +94,14 @@ static void reload_config(void); /* * worker child main loop */ -void do_worker_child(void) +void +do_worker_child(void) { - sigjmp_buf local_sigjmp_buf; + sigjmp_buf local_sigjmp_buf; MemoryContext WorkerMemoryContext; - + ereport(DEBUG1, - (errmsg("I am %d", getpid()))); + (errmsg("I am %d", getpid()))); /* Identify myself via ps */ init_ps_display("", "", "", ""); @@ -117,13 +118,13 @@ void do_worker_child(void) signal(SIGUSR2, SIG_IGN); signal(SIGPIPE, SIG_IGN); - /* Create per loop iteration memory context */ + /* Create per loop iteration memory context */ WorkerMemoryContext = AllocSetContextCreate(TopMemoryContext, - "Worker_main_loop", - ALLOCSET_DEFAULT_MINSIZE, - ALLOCSET_DEFAULT_INITSIZE, - ALLOCSET_DEFAULT_MAXSIZE); - + "Worker_main_loop", + ALLOCSET_DEFAULT_MINSIZE, + ALLOCSET_DEFAULT_INITSIZE, + ALLOCSET_DEFAULT_MAXSIZE); + MemoryContextSwitchTo(TopMemoryContext); /* Initialize my backend status */ @@ -132,7 +133,7 @@ void do_worker_child(void) /* Initialize per process context */ pool_init_process_context(); - if (sigsetjmp(local_sigjmp_buf, 1) != 0) + if (sigsetjmp(local_sigjmp_buf, 1) != 0) { pool_signal(SIGALRM, SIG_IGN); error_context_stack = NULL; @@ -146,7 +147,7 @@ void do_worker_child(void) for (;;) { - MemoryContextSwitchTo(WorkerMemoryContext); + MemoryContextSwitchTo(WorkerMemoryContext); MemoryContextResetAndDeleteChildren(WorkerMemoryContext); CHECK_REQUEST; @@ -163,42 +164,43 @@ void do_worker_child(void) if (pool_config->sr_check_period > 0 && STREAM) { establish_persistent_connection(); - PG_TRY(); - { + PG_TRY(); + { POOL_NODE_STATUS *node_status; - int i; + int i; - /* Do replication time lag checking */ - check_replication_time_lag(); + /* Do replication time lag checking */ + check_replication_time_lag(); /* Check node status */ node_status = verify_backend_node_status(slots); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { ereport(DEBUG1, - (errmsg("node status[%d]: %d", i, node_status[i]))); + (errmsg("node status[%d]: %d", i, node_status[i]))); if (node_status[i] == POOL_NODE_STATUS_INVALID) { - int n; + int n; + ereport(LOG, (errmsg("pgpool_worker_child: invalid node found %d", i))); if (pool_config->detach_false_primary) { n = i; - degenerate_backend_set(&n, 1, REQ_DETAIL_SWITCHOVER|REQ_DETAIL_CONFIRMED); + degenerate_backend_set(&n, 1, REQ_DETAIL_SWITCHOVER | REQ_DETAIL_CONFIRMED); } } } - } - PG_CATCH(); - { - discard_persistent_connection(); - sleep(pool_config->sr_check_period); - PG_RE_THROW(); - } - PG_END_TRY(); - + } + PG_CATCH(); + { + discard_persistent_connection(); + sleep(pool_config->sr_check_period); + PG_RE_THROW(); + } + PG_END_TRY(); + /* Discard persistent connections */ discard_persistent_connection(); } @@ -210,42 +212,44 @@ void do_worker_child(void) /* * Establish persistent connection to backend */ -static void establish_persistent_connection(void) +static void +establish_persistent_connection(void) { - int i; + int i; BackendInfo *bkinfo; - char *password = get_pgpool_config_user_password(pool_config->sr_check_user, - pool_config->sr_check_password); + char *password = get_pgpool_config_user_password(pool_config->sr_check_user, + pool_config->sr_check_password); - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; if (slots[i] == NULL) { - bkinfo = pool_get_node_info(i); - slots[i] = make_persistent_db_connection_noerror(i, bkinfo->backend_hostname, - bkinfo->backend_port, - pool_config->sr_check_database, - pool_config->sr_check_user, - password?password:"", true); + bkinfo = pool_get_node_info(i); + slots[i] = make_persistent_db_connection_noerror(i, bkinfo->backend_hostname, + bkinfo->backend_port, + pool_config->sr_check_database, + pool_config->sr_check_user, + password ? password : "", true); } } - if(password) + if (password) pfree(password); } /* * Discard persistent connection to backend */ -static void discard_persistent_connection(void) +static void +discard_persistent_connection(void) { - int i; + int i; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (slots[i]) { @@ -258,16 +262,17 @@ static void discard_persistent_connection(void) /* * Check replication time lag */ -static void check_replication_time_lag(void) +static void +check_replication_time_lag(void) { /* backend server version cache */ - static int server_version[MAX_NUM_BACKENDS]; + static int server_version[MAX_NUM_BACKENDS]; - int i; - int active_nodes = 0; + int i; + int active_nodes = 0; POOL_SELECT_RESULT *res; unsigned long long int lsn[MAX_NUM_BACKENDS]; - char *query; + char *query; BackendInfo *bkinfo; unsigned long long int lag; ErrorContextCallback callback; @@ -285,7 +290,7 @@ static void check_replication_time_lag(void) } /* Count healthy nodes */ - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (VALID_BACKEND(i)) active_nodes++; @@ -293,8 +298,10 @@ static void check_replication_time_lag(void) if (active_nodes <= 1) { - /* If there's only one or less active node, there's no point - * to do checking */ + /* + * If there's only one or less active node, there's no point to do + * checking + */ return; } @@ -306,17 +313,17 @@ static void check_replication_time_lag(void) callback.previous = error_context_stack; error_context_stack = &callback; - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; if (!slots[i]) { - ereport(ERROR, - (errmsg("Failed to check replication time lag"), - errdetail("No persistent db connection for the node %d",i), - errhint("check sr_check_user and sr_check_password"))); + ereport(ERROR, + (errmsg("Failed to check replication time lag"), + errdetail("No persistent db connection for the node %d", i), + errhint("check sr_check_user and sr_check_password"))); } @@ -324,14 +331,17 @@ static void check_replication_time_lag(void) { query = "SELECT current_setting('server_version_num')"; - /* Get backend server version. If the query fails, keep previous info. */ + /* + * Get backend server version. If the query fails, keep previous + * info. + */ if (get_query_result(slots, i, query, &res) == 0) { server_version[i] = atoi(res->data[0]); ereport(DEBUG1, (errmsg("backend %d server version: %d", i, server_version[i]))); } - + } if (PRIMARY_NODE_ID == i) @@ -360,7 +370,7 @@ static void check_replication_time_lag(void) } } - for (i=0;i<NUM_BACKENDS;i++) + for (i = 0; i < NUM_BACKENDS; i++) { if (!VALID_BACKEND(i)) continue; @@ -383,9 +393,9 @@ static void check_replication_time_lag(void) pool_config->log_standby_delay == LSD_OVER_THRESHOLD && lag > pool_config->delay_threshold)) { - ereport(LOG, - (errmsg("Replication of node:%d is behind %llu bytes from the primary server (node:%d)", - i, lsn[PRIMARY_NODE_ID] - lsn[i], PRIMARY_NODE_ID))); + ereport(LOG, + (errmsg("Replication of node:%d is behind %llu bytes from the primary server (node:%d)", + i, lsn[PRIMARY_NODE_ID] - lsn[i], PRIMARY_NODE_ID))); } } } @@ -393,14 +403,17 @@ static void check_replication_time_lag(void) error_context_stack = callback.previous; } -static void CheckReplicationTimeLagErrorCb(void *arg) +static void +CheckReplicationTimeLagErrorCb(void *arg) { errcontext("while checking replication time lag"); } + /* * Convert logid/recoff style text to 64bit log location (LSN) */ -static unsigned long long int text_to_lsn(char *text) +static unsigned long long int +text_to_lsn(char *text) { /* * WAL segment size in bytes. XXX We should fetch this from @@ -412,14 +425,14 @@ static unsigned long long int text_to_lsn(char *text) unsigned int xrecoff; unsigned long long int lsn; - if (sscanf(text, "%X/%X", &xlogid, &xrecoff) != 2) + if (sscanf(text, "%X/%X", &xlogid, &xrecoff) !=2) { - ereport(ERROR, - (errmsg("invalid LSN format"), - errdetail("wrong log location format: %s", text))); + ereport(ERROR, + (errmsg("invalid LSN format"), + errdetail("wrong log location format: %s", text))); } - lsn = xlogid * ((unsigned long long int)0xffffffff - WALSEGMENTSIZE) + xrecoff; + lsn = xlogid * ((unsigned long long int) 0xffffffff - WALSEGMENTSIZE) + xrecoff; #ifdef DEBUG ereport(LOG, (errmsg("lsn: %X %X %llX", xlogid, xrecoff, lsn))); @@ -429,7 +442,7 @@ static unsigned long long int text_to_lsn(char *text) static RETSIGTYPE my_signal_handler(int sig) { - int save_errno = errno; + int save_errno = errno; POOL_SETMASK(&BlockSig); @@ -458,20 +471,23 @@ static RETSIGTYPE my_signal_handler(int sig) static RETSIGTYPE reload_config_handler(int sig) { - int save_errno = errno; + int save_errno = errno; + POOL_SETMASK(&BlockSig); reload_config_request = 1; POOL_SETMASK(&UnBlockSig); errno = save_errno; } -static void reload_config(void) +static void +reload_config(void) { ereport(LOG, (errmsg("reloading config file"))); - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); if (pool_config->enable_pool_hba) load_hba(get_hba_file_name()); reload_config_request = 0; @@ -483,9 +499,10 @@ static void reload_config(void) * for POOL_SELECT_RESULT and pass it as "res". It is guaranteed that no * exception occurs within this function. */ -int get_query_result(POOL_CONNECTION_POOL_SLOT **slots, int backend_id, char *query, POOL_SELECT_RESULT **res) +int +get_query_result(POOL_CONNECTION_POOL_SLOT * *slots, int backend_id, char *query, POOL_SELECT_RESULT * *res) { - int sts = -1; + int sts = -1; MemoryContext oldContext = CurrentMemoryContext; PG_TRY(); diff --git a/src/test/C/test_extended.c b/src/test/C/test_extended.c index c7dbad21a..0eb568c77 100644 --- a/src/test/C/test_extended.c +++ b/src/test/C/test_extended.c @@ -36,47 +36,52 @@ #include "libpq-fe.h" #include "libpq/libpq-fs.h" -int main(int argc, char **argv) { - char *connect_string = "user=t-ishii dbname=test port=5432"; - int doTrace = 1; /* set 1 to start libpq trace */ - int doTransaction = 1; /* set 1 to start explicit transaction */ - int doSleep = 0; /* set non 0 seconds to sleep after connection and beforfe starting command */ +int +main(int argc, char **argv) +{ + char *connect_string = "user=t-ishii dbname=test port=5432"; + int doTrace = 1; /* set 1 to start libpq trace */ + int doTransaction = 1; /* set 1 to start explicit transaction */ + int doSleep = 0; /* set non 0 seconds to sleep after connection + * and beforfe starting command */ /* SQL commands to be executed */ static char *commands[] = { - "SAVEPOINT S1", - "UPDATE t1 SET k = 1", - "ROLLBACK TO S1", - "SELECT 1", - "RELEASE SAVEPOINT S1" + "SAVEPOINT S1", + "UPDATE t1 SET k = 1", + "ROLLBACK TO S1", + "SELECT 1", + "RELEASE SAVEPOINT S1" }; - PGconn *conn; - PGresult *res; - int i; + PGconn *conn; + PGresult *res; + int i; conn = PQconnectdb(connect_string); - if (PQstatus(conn) == CONNECTION_BAD) { + if (PQstatus(conn) == CONNECTION_BAD) + { printf("Unable to connect to db\n"); PQfinish(conn); return 1; } if (doSleep) - sleep(doSleep); + sleep(doSleep); - if(doTrace == 1) - PQtrace(conn, stdout); + if (doTrace == 1) + PQtrace(conn, stdout); - if(doTransaction) - PQexec(conn,"BEGIN;"); + if (doTransaction) + PQexec(conn, "BEGIN;"); - for (i=0;i<sizeof(commands)/sizeof(char *);i++) + for (i = 0; i < sizeof(commands) / sizeof(char *); i++) { - char *command = commands[i]; - + char *command = commands[i]; + res = PQexecParams(conn, command, 0, NULL, NULL, NULL, NULL, 0); - switch(PQresultStatus(res)) { + switch (PQresultStatus(res)) + { case PGRES_COMMAND_OK: case PGRES_TUPLES_OK: fprintf(stderr, "\"%s\" : succeeded\n", command); @@ -89,10 +94,11 @@ int main(int argc, char **argv) { } - if(doTransaction == 1) { - PQexec(conn,"COMMIT;"); + if (doTransaction == 1) + { + PQexec(conn, "COMMIT;"); } - + PQfinish(conn); return 0; } diff --git a/src/test/parser/main.c b/src/test/parser/main.c index 451e709d9..f34dc98b8 100644 --- a/src/test/parser/main.c +++ b/src/test/parser/main.c @@ -9,17 +9,19 @@ #include <stdlib.h> #include <unistd.h> -enum { +enum +{ TEST_CONTINUE, TEST_QUIT }; -extern int GetDatabaseEncoding(void); +extern int GetDatabaseEncoding(void); int command(const char *cmd) { - char name[1024], value[1024]; + char name[1024], + value[1024]; if (*cmd == 'q') return TEST_QUIT; @@ -47,19 +49,20 @@ command(const char *cmd) return TEST_CONTINUE; } -int main(int argc, char **argv) +int +main(int argc, char **argv) { - List *tree; - ListCell *l; - int state = TEST_CONTINUE; - int notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout))); - char line[1024]; + List *tree; + ListCell *l; + int state = TEST_CONTINUE; + int notty = (!isatty(fileno(stdin)) || !isatty(fileno(stdout))); + char line[1024]; while (state != TEST_QUIT) { if (!notty) fprintf(stdout, "> "); - + if (!fgets(line, 1024, stdin)) break; @@ -84,7 +87,8 @@ int main(int argc, char **argv) { foreach(l, tree) { - Node *node = (Node *) lfirst(l); + Node *node = (Node *) lfirst(l); + printf("%s\n", nodeToString(node)); } } diff --git a/src/test/parser/pool.h b/src/test/parser/pool.h index be1ddcdd9..d5718f2b4 100644 --- a/src/test/parser/pool.h +++ b/src/test/parser/pool.h @@ -8,4 +8,3 @@ #define child_exit exit #endif - diff --git a/src/test/regression/tests/010.rewrite_timestamp/timestamp/main.c b/src/test/regression/tests/010.rewrite_timestamp/timestamp/main.c index a990db777..1bef90723 100644 --- a/src/test/regression/tests/010.rewrite_timestamp/timestamp/main.c +++ b/src/test/regression/tests/010.rewrite_timestamp/timestamp/main.c @@ -8,60 +8,68 @@ #include "parser/parser.h" /* for get_current_timestamp() (MASTER() macro) */ -POOL_REQUEST_INFO _req_info; +POOL_REQUEST_INFO _req_info; POOL_REQUEST_INFO *Req_info = &_req_info; + POOL_CONFIG _pool_config; POOL_CONFIG *pool_config = &_pool_config; ProcessType processType; -typedef struct { - char *attrname; /* attribute name */ - char *adsrc; /* default value expression */ - int use_timestamp; -} TSAttr; - -typedef struct { - int relnatts; - TSAttr attr[4]; -} TSRel; - - -TSRel rc[2] = { - { 4, { - { "c1", "", 0 }, - { "c2", "", 1 }, - { "c3", "", 0 }, - { "c4", "", 1 } - } }, - { 4, { - { "c1", "", 0 }, - { "c2", "", 0 }, - { "c3", "", 0 }, - { "c4", "", 0 } - } } +typedef struct +{ + char *attrname; /* attribute name */ + char *adsrc; /* default value expression */ + int use_timestamp; +} TSAttr; + +typedef struct +{ + int relnatts; + TSAttr attr[4]; +} TSRel; + + +TSRel rc[2] = { + {4, { + {"c1", "", 0}, + {"c2", "", 1}, + {"c3", "", 0}, + {"c4", "", 1} + }}, + {4, { + {"c1", "", 0}, + {"c2", "", 0}, + {"c3", "", 0}, + {"c4", "", 0} + }} }; -int pool_virtual_master_db_node_id(void) +int +pool_virtual_master_db_node_id(void) { return 0; } -bool pool_has_pgpool_regclass(void) +bool +pool_has_pgpool_regclass(void) { return false; } -bool pool_has_to_regclass(void) +bool +pool_has_to_regclass(void) { return false; } -char *remove_quotes_and_schema_from_relname(char *table) +char * +remove_quotes_and_schema_from_relname(char *table) { return table; } -int pool_get_major_version(void) +int +pool_get_major_version(void) { return PROTO_MAJOR_V3; } @@ -74,7 +82,7 @@ pool_create_relcache(int cachesize, char *sql, func_ptr register_func, func_ptr /* dummy result of relcache (attrname, adsrc, usetimestamp)*/ void * -pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table) +pool_search_relcache(POOL_RELCACHE * relcache, POOL_CONNECTION_POOL * backend, char *table) { if (strcmp(table, "\"rel1\"") == 0) return (void *) &(rc[0]); @@ -83,7 +91,9 @@ pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, cha } /* dummy result of "SELECT now()" */ -void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result, int major) { +void +do_query(POOL_CONNECTION * backend, char *query, POOL_SELECT_RESULT * *result, int major) +{ static POOL_SELECT_RESULT res; static char *data[1] = { "2009-01-01 23:59:59.123456+09" @@ -95,7 +105,8 @@ void do_query(POOL_CONNECTION *backend, char *query, POOL_SELECT_RESULT **result *result = &res; } -char *make_table_name_from_rangevar(RangeVar *rangevar) +char * +make_table_name_from_rangevar(RangeVar *rangevar) { /* XXX: alias (AS ...) is left */ return nodeToString(rangevar); @@ -104,17 +115,18 @@ char *make_table_name_from_rangevar(RangeVar *rangevar) int main(int argc, char **argv) { - char *query; - List *tree; - ListCell *l; - StartupPacket sp; - POOL_CONNECTION_POOL backend; + char *query; + List *tree; + ListCell *l; + StartupPacket sp; + POOL_CONNECTION_POOL backend; POOL_CONNECTION_POOL_SLOT slot; - POOL_SENT_MESSAGE msg; - POOL_QUERY_CONTEXT ctx; + POOL_SENT_MESSAGE msg; + POOL_QUERY_CONTEXT ctx; + backend.slots[0] = &slot; slot.sp = &sp; - bool error; + bool error; MemoryContextInit(); @@ -137,8 +149,9 @@ main(int argc, char **argv) { msg.num_tsparams = 0; msg.query_context = &ctx; - Node *node = (Node *) lfirst(l); - query = rewrite_timestamp(&backend, ((RawStmt *) node)->stmt, false, &msg); + Node *node = (Node *) lfirst(l); + + query = rewrite_timestamp(&backend, ((RawStmt *) node)->stmt, false, &msg); if (query) printf("%s\n", query); else @@ -149,14 +162,47 @@ main(int argc, char **argv) return 0; } -void free_select_result(POOL_SELECT_RESULT *result) {} -POOL_SESSION_CONTEXT *pool_get_session_context(bool noerror) {return NULL;} -int pg_frontend_exists(void) {return 0;} -int get_frontend_protocol_version(void) {return 0;} -int set_pg_frontend_blocking(bool blocking) {return 0;} -int send_to_pg_frontend(char* data, int len, bool flush) {return 0;} -int pool_send_to_frontend(char* data, int len, bool flush) {return 0;} -int pool_frontend_exists(void) {return 0;} -void ExceptionalCondition - (const char *conditionName,const char *errorType, - const char *fileName, int lineNumber) {} +void +free_select_result(POOL_SELECT_RESULT * result) +{ +} +POOL_SESSION_CONTEXT * +pool_get_session_context(bool noerror) +{ + return NULL; +} +int +pg_frontend_exists(void) +{ + return 0; +} +int +get_frontend_protocol_version(void) +{ + return 0; +} +int +set_pg_frontend_blocking(bool blocking) +{ + return 0; +} +int +send_to_pg_frontend(char *data, int len, bool flush) +{ + return 0; +} +int +pool_send_to_frontend(char *data, int len, bool flush) +{ + return 0; +} +int +pool_frontend_exists(void) +{ + return 0; +} +void ExceptionalCondition + (const char *conditionName, const char *errorType, + const char *fileName, int lineNumber) +{ +} diff --git a/src/tools/fe_port.c b/src/tools/fe_port.c index 8697012bb..054df100a 100644 --- a/src/tools/fe_port.c +++ b/src/tools/fe_port.c @@ -32,13 +32,13 @@ #include "utils/fe_ports.h" -int _fe_error_level = 0; -const char* _filename; -const char* _funcname; -int _lineno; -int _print_timestamp = 0; +int _fe_error_level = 0; +const char *_filename; +const char *_funcname; +int _lineno; +int _print_timestamp = 0; -static const char * error_severity(int elevel); +static const char *error_severity(int elevel); static char *nowsec(void); #define MAXSTRFTIME 128 @@ -66,40 +66,41 @@ errfinish(int dummy,...) { } -void errmsg(const char *fmt,...) +void +errmsg(const char *fmt,...) { va_list ap; #ifdef HAVE_ASPRINTF - char *fmt2; - int len; + char *fmt2; + int len; #endif #ifdef HAVE_ASPRINTF if (_print_timestamp) - len = asprintf(&fmt2, "%s %s: pid %d: %s\n", nowsec(), error_severity(_fe_error_level), (int)getpid(), fmt); + len = asprintf(&fmt2, "%s %s: pid %d: %s\n", nowsec(), error_severity(_fe_error_level), (int) getpid(), fmt); else - len = asprintf(&fmt2, "%s: pid %d: %s\n", error_severity(_fe_error_level),(int)getpid(), fmt); - + len = asprintf(&fmt2, "%s: pid %d: %s\n", error_severity(_fe_error_level), (int) getpid(), fmt); + if (len >= 0 && fmt2) { va_start(ap, fmt); vfprintf(stderr, fmt2, ap); va_end(ap); fflush(stderr); - free(fmt2); + free(fmt2); } #else if (_print_timestamp) - fprintf(stderr, "%s %s: pid %d: ", nowsec(),error_severity(_fe_error_level), (int)getpid()); + fprintf(stderr, "%s %s: pid %d: ", nowsec(), error_severity(_fe_error_level), (int) getpid()); else - fprintf(stderr, "%s: pid %d: ",error_severity(_fe_error_level), (int)getpid()); - + fprintf(stderr, "%s: pid %d: ", error_severity(_fe_error_level), (int) getpid()); + va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); fprintf(stderr, "\n"); #endif - + } /* @@ -109,7 +110,7 @@ static const char * error_severity(int elevel) { const char *prefix; - + switch (elevel) { case DEBUG1: @@ -145,15 +146,16 @@ error_severity(int elevel) prefix = "???"; break; } - + return prefix; } -static char *nowsec(void) +static char * +nowsec(void) { static char strbuf[MAXSTRFTIME]; - time_t now = time(NULL); - + time_t now = time(NULL); + strftime(strbuf, MAXSTRFTIME, "%Y-%m-%d %H:%M:%S", localtime(&now)); return strbuf; } @@ -163,10 +165,12 @@ errstart(int elevel, const char *filename, int lineno, const char *funcname) { _fe_error_level = elevel; - /* - * This is a basic version and for now we just supress all messages below WARNING for frontend + + /* + * This is a basic version and for now we just supress all messages below + * WARNING for frontend */ - if(_fe_error_level < WARNING) + if (_fe_error_level < WARNING) return 0; _filename = filename; _lineno = lineno; diff --git a/src/tools/pcp/pcp_frontend_client.c b/src/tools/pcp/pcp_frontend_client.c index a55a292fe..372a1b641 100644 --- a/src/tools/pcp/pcp_frontend_client.c +++ b/src/tools/pcp/pcp_frontend_client.c @@ -36,19 +36,19 @@ #include "utils/getopt_long.h" #endif -const char* progname = NULL; -const char * get_progname(const char *argv0); -char *last_dir_separator(const char *filename); +const char *progname = NULL; +const char *get_progname(const char *argv0); +char *last_dir_separator(const char *filename); static void usage(void); static inline bool app_require_nodeID(void); -static void output_watchdog_info_result(PCPResultInfo* pcpResInfo, bool verbose); -static void output_procinfo_result(PCPResultInfo* pcpResInfo, bool all, bool verbose); -static void output_proccount_result(PCPResultInfo* pcpResInfo, bool verbose); -static void output_poolstatus_result(PCPResultInfo* pcpResInfo, bool verbose); -static void output_nodeinfo_result(PCPResultInfo* pcpResInfo, bool verbose); -static void output_nodecount_result(PCPResultInfo* pcpResInfo, bool verbose); -static char* backend_status_to_string(BackendInfo *bi); +static void output_watchdog_info_result(PCPResultInfo * pcpResInfo, bool verbose); +static void output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose); +static void output_proccount_result(PCPResultInfo * pcpResInfo, bool verbose); +static void output_poolstatus_result(PCPResultInfo * pcpResInfo, bool verbose); +static void output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool verbose); +static void output_nodecount_result(PCPResultInfo * pcpResInfo, bool verbose); +static char *backend_status_to_string(BackendInfo * bi); typedef enum { @@ -64,53 +64,53 @@ typedef enum PCP_STOP_PGPOOL, PCP_WATCHDOG_INFO, UNKNOWN, -} PCP_UTILITIES; +} PCP_UTILITIES; struct AppTypes { const char *app_name; PCP_UTILITIES app_type; - const char* allowed_options; - const char* description; + const char *allowed_options; + const char *description; }; struct AppTypes AllAppTypes[] = - { - {"pcp_attach_node", PCP_ATTACH_NODE,"n:h:p:U:wWvd","attach a node from pgpool-II"}, - {"pcp_detach_node", PCP_DETACH_NODE,"n:h:p:U:gwWvd","detach a node from pgpool-II"}, - {"pcp_node_count", PCP_NODE_COUNT,"h:p:U:wWvd","display the total number of nodes under pgpool-II's control"}, - {"pcp_node_info", PCP_NODE_INFO,"n:h:p:U:wWvd", "display a pgpool-II node's information"}, - {"pcp_pool_status", PCP_POOL_STATUS,"h:p:U:wWvd", "display pgpool configuration and status"}, - {"pcp_proc_count", PCP_PROC_COUNT,"h:p:U:wWvd", "display the list of pgpool-II child process PIDs"}, - {"pcp_proc_info", PCP_PROC_INFO,"h:p:P:U:awWvd","display a pgpool-II child process' information"}, - {"pcp_promote_node", PCP_PROMOTE_NODE,"n:h:p:U:gwWvd", "promote a node as new master from pgpool-II"}, - {"pcp_recovery_node", PCP_RECOVERY_NODE,"n:h:p:U:wWvd","recover a node"}, - {"pcp_stop_pgpool", PCP_STOP_PGPOOL,"m:h:p:U:wWvd", "terminate pgpool-II"}, - {"pcp_watchdog_info", PCP_WATCHDOG_INFO,"n:h:p:U:wWvd", "display a pgpool-II watchdog's information"}, - {NULL, UNKNOWN,NULL,NULL}, - }; -struct AppTypes* current_app_type; +{ + {"pcp_attach_node", PCP_ATTACH_NODE, "n:h:p:U:wWvd", "attach a node from pgpool-II"}, + {"pcp_detach_node", PCP_DETACH_NODE, "n:h:p:U:gwWvd", "detach a node from pgpool-II"}, + {"pcp_node_count", PCP_NODE_COUNT, "h:p:U:wWvd", "display the total number of nodes under pgpool-II's control"}, + {"pcp_node_info", PCP_NODE_INFO, "n:h:p:U:wWvd", "display a pgpool-II node's information"}, + {"pcp_pool_status", PCP_POOL_STATUS, "h:p:U:wWvd", "display pgpool configuration and status"}, + {"pcp_proc_count", PCP_PROC_COUNT, "h:p:U:wWvd", "display the list of pgpool-II child process PIDs"}, + {"pcp_proc_info", PCP_PROC_INFO, "h:p:P:U:awWvd", "display a pgpool-II child process' information"}, + {"pcp_promote_node", PCP_PROMOTE_NODE, "n:h:p:U:gwWvd", "promote a node as new master from pgpool-II"}, + {"pcp_recovery_node", PCP_RECOVERY_NODE, "n:h:p:U:wWvd", "recover a node"}, + {"pcp_stop_pgpool", PCP_STOP_PGPOOL, "m:h:p:U:wWvd", "terminate pgpool-II"}, + {"pcp_watchdog_info", PCP_WATCHDOG_INFO, "n:h:p:U:wWvd", "display a pgpool-II watchdog's information"}, + {NULL, UNKNOWN, NULL, NULL}, +}; +struct AppTypes *current_app_type; int main(int argc, char **argv) { - char* host = NULL; - int port = 9898; - char* user = NULL; - char* pass = NULL; - int nodeID = -1; - int processID = 0; - int ch; - char shutdown_mode = 's'; - int optindex; - int i; - bool all = false; - bool debug = false; - bool need_password = true; - bool gracefully = false; - bool verbose = false; - PCPConnInfo* pcpConn; - PCPResultInfo* pcpResInfo; + char *host = NULL; + int port = 9898; + char *user = NULL; + char *pass = NULL; + int nodeID = -1; + int processID = 0; + int ch; + char shutdown_mode = 's'; + int optindex; + int i; + bool all = false; + bool debug = false; + bool need_password = true; + bool gracefully = false; + bool verbose = false; + PCPConnInfo *pcpConn; + PCPResultInfo *pcpResInfo; /* here we put all the allowed long options for all utilities */ static struct option long_options[] = { @@ -131,21 +131,21 @@ main(int argc, char **argv) {"watchdog-id", required_argument, NULL, 'n'}, {NULL, 0, NULL, 0} }; - + /* Identify the utility app */ progname = get_progname(argv[0]); - for( i =0; ;i++) + for (i = 0;; i++) { current_app_type = &AllAppTypes[i]; - if(current_app_type->app_type == UNKNOWN) + if (current_app_type->app_type == UNKNOWN) break; if (strcmp(current_app_type->app_name, progname) == 0) break; } - if(current_app_type->app_type == UNKNOWN) + if (current_app_type->app_type == UNKNOWN) { - fprintf(stderr, "%s is a invalid PCP utility\n",progname); + fprintf(stderr, "%s is a invalid PCP utility\n", progname); exit(1); } @@ -159,12 +159,13 @@ main(int argc, char **argv) else if (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") == 0) { - fprintf(stderr, "%s (%s) %s\n",progname,PACKAGE, VERSION); + fprintf(stderr, "%s (%s) %s\n", progname, PACKAGE, VERSION); exit(0); } } - while ((ch = getopt_long(argc, argv, current_app_type->allowed_options, long_options, &optindex)) != -1) { + while ((ch = getopt_long(argc, argv, current_app_type->allowed_options, long_options, &optindex)) != -1) + { switch (ch) { case 'd': @@ -198,13 +199,13 @@ main(int argc, char **argv) shutdown_mode = 'i'; else { - fprintf(stderr, "%s: Invalid shutdown mode \"%s\", must be either \"smart\" \"immediate\" or \"fast\" \n",progname,optarg); + fprintf(stderr, "%s: Invalid shutdown mode \"%s\", must be either \"smart\" \"immediate\" or \"fast\" \n", progname, optarg); exit(1); } } else { - fprintf(stderr, "Invalid argument \"%s\", Try \"%s --help\" for more information.\n",optarg,progname); + fprintf(stderr, "Invalid argument \"%s\", Try \"%s --help\" for more information.\n", optarg, progname); exit(1); } break; @@ -219,7 +220,7 @@ main(int argc, char **argv) { if (nodeID < 0) { - fprintf(stderr, "%s: Invalid watchdog-id \"%s\", must be a positive number or zero for a local watchdog node\n",progname,optarg); + fprintf(stderr, "%s: Invalid watchdog-id \"%s\", must be a positive number or zero for a local watchdog node\n", progname, optarg); exit(0); } } @@ -227,7 +228,7 @@ main(int argc, char **argv) { if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { - fprintf(stderr, "%s: Invalid node-id \"%s\", must be between 0 and %d\n",progname,optarg,MAX_NUM_BACKENDS); + fprintf(stderr, "%s: Invalid node-id \"%s\", must be between 0 and %d\n", progname, optarg, MAX_NUM_BACKENDS); exit(0); } } @@ -237,16 +238,16 @@ main(int argc, char **argv) port = atoi(optarg); if (port <= 1024 || port > 65535) { - fprintf(stderr, "%s: Invalid port number \"%s\", must be between 1024 and 65535\n",progname,optarg); + fprintf(stderr, "%s: Invalid port number \"%s\", must be between 1024 and 65535\n", progname, optarg); exit(0); } break; - case 'P': /* PID */ + case 'P': /* PID */ processID = atoi(optarg); - if (processID <= 0 ) + if (processID <= 0) { - fprintf(stderr, "%s: Invalid process-id \"%s\", must be greater than 0\n",progname,optarg); + fprintf(stderr, "%s: Invalid process-id \"%s\", must be greater than 0\n", progname, optarg); exit(0); } break; @@ -261,10 +262,11 @@ main(int argc, char **argv) case '?': default: + /* * getopt_long whould already have emitted a complaint */ - fprintf(stderr, "Try \"%s --help\" for more information.\n\n",progname); + fprintf(stderr, "Try \"%s --help\" for more information.\n\n", progname); exit(1); } } @@ -277,18 +279,18 @@ main(int argc, char **argv) if (current_app_type->app_type == PCP_PROC_INFO && processID <= 0) { processID = atoi(argv[optind]); - if (processID <= 0 ) + if (processID <= 0) { - fprintf(stderr, "%s: Invalid process-id \"%s\", must be greater than 0\n",progname,optarg); + fprintf(stderr, "%s: Invalid process-id \"%s\", must be greater than 0\n", progname, optarg); exit(0); } } else if (current_app_type->app_type == PCP_WATCHDOG_INFO && nodeID < 0) { nodeID = atoi(argv[optind]); - if (nodeID < 0 ) + if (nodeID < 0) { - fprintf(stderr, "%s: Invalid watchdog-id \"%s\", must be a positive number or zero for local watchdog node\n",progname,optarg); + fprintf(stderr, "%s: Invalid watchdog-id \"%s\", must be a positive number or zero for local watchdog node\n", progname, optarg); exit(0); } } @@ -297,7 +299,7 @@ main(int argc, char **argv) nodeID = atoi(argv[optind]); if (nodeID < 0 || nodeID > MAX_NUM_BACKENDS) { - fprintf(stderr, "%s: Invalid node-id \"%s\", must be between 0 and %d\n",progname,optarg,MAX_NUM_BACKENDS); + fprintf(stderr, "%s: Invalid node-id \"%s\", must be between 0 and %d\n", progname, optarg, MAX_NUM_BACKENDS); exit(0); } } @@ -308,12 +310,12 @@ main(int argc, char **argv) optind++; } - if(nodeID < 0) + if (nodeID < 0) { if (app_require_nodeID()) { - fprintf(stderr, "%s: missing node-id\n",progname); - fprintf(stderr, "Try \"%s --help\" for more information.\n\n",progname); + fprintf(stderr, "%s: missing node-id\n", progname); + fprintf(stderr, "Try \"%s --help\" for more information.\n\n", progname); exit(1); } else if (current_app_type->app_type == PCP_WATCHDOG_INFO) @@ -329,10 +331,10 @@ main(int argc, char **argv) need_password = false; } - pcpConn = pcp_connect(host, port, user, pass, debug?stdout:NULL); - if(PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) + pcpConn = pcp_connect(host, port, user, pass, debug ? stdout : NULL); + if (PCPConnectionStatus(pcpConn) != PCP_CONNECTION_OK) { - fprintf(stderr, "%s\n",pcp_get_last_error(pcpConn)?pcp_get_last_error(pcpConn):"Unknown Error"); + fprintf(stderr, "%s\n", pcp_get_last_error(pcpConn) ? pcp_get_last_error(pcpConn) : "Unknown Error"); exit(1); } @@ -341,15 +343,15 @@ main(int argc, char **argv) */ if (current_app_type->app_type == PCP_ATTACH_NODE) { - pcpResInfo = pcp_attach_node(pcpConn,nodeID); + pcpResInfo = pcp_attach_node(pcpConn, nodeID); } else if (current_app_type->app_type == PCP_DETACH_NODE) { if (gracefully) - pcpResInfo = pcp_detach_node_gracefully(pcpConn,nodeID); + pcpResInfo = pcp_detach_node_gracefully(pcpConn, nodeID); else - pcpResInfo = pcp_detach_node(pcpConn,nodeID); + pcpResInfo = pcp_detach_node(pcpConn, nodeID); } else if (current_app_type->app_type == PCP_NODE_COUNT) @@ -359,7 +361,7 @@ main(int argc, char **argv) else if (current_app_type->app_type == PCP_NODE_INFO) { - pcpResInfo = pcp_node_info(pcpConn,nodeID); + pcpResInfo = pcp_node_info(pcpConn, nodeID); } else if (current_app_type->app_type == PCP_POOL_STATUS) @@ -380,9 +382,9 @@ main(int argc, char **argv) else if (current_app_type->app_type == PCP_PROMOTE_NODE) { if (gracefully) - pcpResInfo = pcp_promote_node_gracefully(pcpConn,nodeID); + pcpResInfo = pcp_promote_node_gracefully(pcpConn, nodeID); else - pcpResInfo = pcp_promote_node(pcpConn,nodeID); + pcpResInfo = pcp_promote_node(pcpConn, nodeID); } else if (current_app_type->app_type == PCP_RECOVERY_NODE) @@ -397,25 +399,25 @@ main(int argc, char **argv) else if (current_app_type->app_type == PCP_WATCHDOG_INFO) { - pcpResInfo = pcp_watchdog_info(pcpConn,nodeID); + pcpResInfo = pcp_watchdog_info(pcpConn, nodeID); } else { /* should never happen */ - fprintf(stderr,"%s: Invalid pcp process\n",progname); + fprintf(stderr, "%s: Invalid pcp process\n", progname); goto DISCONNECT_AND_EXIT; } - if(pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) + if (pcpResInfo == NULL || PCPResultStatus(pcpResInfo) != PCP_RES_COMMAND_OK) { - fprintf(stderr, "%s\n",pcp_get_last_error(pcpConn)?pcp_get_last_error(pcpConn):"Unknown Error"); + fprintf(stderr, "%s\n", pcp_get_last_error(pcpConn) ? pcp_get_last_error(pcpConn) : "Unknown Error"); goto DISCONNECT_AND_EXIT; } if (pcp_result_is_empty(pcpResInfo)) { - fprintf(stdout,"%s -- Command Successful\n",progname); + fprintf(stdout, "%s -- Command Successful\n", progname); } else { @@ -447,9 +449,9 @@ DISCONNECT_AND_EXIT: } static void -output_nodecount_result(PCPResultInfo* pcpResInfo, bool verbose) +output_nodecount_result(PCPResultInfo * pcpResInfo, bool verbose) { - if(verbose) + if (verbose) { printf("Node Count\n"); printf("____________\n"); @@ -460,11 +462,11 @@ output_nodecount_result(PCPResultInfo* pcpResInfo, bool verbose) } static void -output_nodeinfo_result(PCPResultInfo* pcpResInfo, bool verbose) +output_nodeinfo_result(PCPResultInfo * pcpResInfo, bool verbose) { - BackendInfo *backend_info = (BackendInfo *) pcp_get_binary_data(pcpResInfo,0); - char last_status_change[20]; - struct tm tm; + BackendInfo *backend_info = (BackendInfo *) pcp_get_binary_data(pcpResInfo, 0); + char last_status_change[20]; + struct tm tm; localtime_r(&backend_info->status_changed_time, &tm); strftime(last_status_change, sizeof(last_status_change), "%F %T", &tm); @@ -475,7 +477,7 @@ output_nodeinfo_result(PCPResultInfo* pcpResInfo, bool verbose) backend_info->backend_hostname, backend_info->backend_port, backend_info->backend_status, - backend_info->backend_weight/RAND_MAX, + backend_info->backend_weight / RAND_MAX, backend_status_to_string(backend_info), role_to_str(backend_info->role), backend_info->standby_delay, @@ -487,7 +489,7 @@ output_nodeinfo_result(PCPResultInfo* pcpResInfo, bool verbose) backend_info->backend_hostname, backend_info->backend_port, backend_info->backend_status, - backend_info->backend_weight/RAND_MAX, + backend_info->backend_weight / RAND_MAX, backend_status_to_string(backend_info), role_to_str(backend_info->role), backend_info->standby_delay, @@ -496,29 +498,30 @@ output_nodeinfo_result(PCPResultInfo* pcpResInfo, bool verbose) } static void -output_poolstatus_result(PCPResultInfo* pcpResInfo, bool verbose) +output_poolstatus_result(PCPResultInfo * pcpResInfo, bool verbose) { POOL_REPORT_CONFIG *status; - int i; - int array_size = pcp_result_slot_count(pcpResInfo); + int i; + int array_size = pcp_result_slot_count(pcpResInfo); - if(verbose) + if (verbose) { - for (i=0; i < array_size; i++) + for (i = 0; i < array_size; i++) { - status = (POOL_REPORT_CONFIG *)pcp_get_binary_data(pcpResInfo, i); - printf("Name [%3d]:\t%s\n",i,status?status->name:"NULL"); - printf("Value: \t%s\n",status?status->value:"NULL"); - printf("Description:\t%s\n\n",status?status->desc:"NULL"); + status = (POOL_REPORT_CONFIG *) pcp_get_binary_data(pcpResInfo, i); + printf("Name [%3d]:\t%s\n", i, status ? status->name : "NULL"); + printf("Value: \t%s\n", status ? status->value : "NULL"); + printf("Description:\t%s\n\n", status ? status->desc : "NULL"); } } else { - for (i=0; i < array_size; i++) { - status = (POOL_REPORT_CONFIG *)pcp_get_binary_data(pcpResInfo, i); - if(status == NULL) + for (i = 0; i < array_size; i++) + { + status = (POOL_REPORT_CONFIG *) pcp_get_binary_data(pcpResInfo, i); + if (status == NULL) { - printf("****Data at %d slot is NULL\n",i); + printf("****Data at %d slot is NULL\n", i); continue; } printf("name : %s\nvalue: %s\ndesc : %s\n\n", status->name, status->value, status->desc); @@ -527,19 +530,19 @@ output_poolstatus_result(PCPResultInfo* pcpResInfo, bool verbose) } static void -output_proccount_result(PCPResultInfo* pcpResInfo, bool verbose) +output_proccount_result(PCPResultInfo * pcpResInfo, bool verbose) { - int i; - int process_count = pcp_get_data_length(pcpResInfo, 0) / sizeof(int); - int *process_list = (int *)pcp_get_binary_data(pcpResInfo, 0); + int i; + int process_count = pcp_get_data_length(pcpResInfo, 0) / sizeof(int); + int *process_list = (int *) pcp_get_binary_data(pcpResInfo, 0); if (verbose) { printf("No \t | \t PID\n"); printf("_____________________\n"); for (i = 0; i < process_count; i++) - printf("%d \t | \t %d\n", i,process_list[i]); - printf("\nTotal Processes:%d\n",process_count); + printf("%d \t | \t %d\n", i, process_list[i]); + printf("\nTotal Processes:%d\n", process_count); } else { @@ -550,17 +553,18 @@ output_proccount_result(PCPResultInfo* pcpResInfo, bool verbose) } static void -output_procinfo_result(PCPResultInfo* pcpResInfo, bool all, bool verbose) +output_procinfo_result(PCPResultInfo * pcpResInfo, bool all, bool verbose) { - bool printed = false; - int i; - char * frmt; - char strcreatetime[128]; - char strstarttime[128]; - int array_size = pcp_result_slot_count(pcpResInfo); + bool printed = false; + int i; + char *frmt; + char strcreatetime[128]; + char strstarttime[128]; + int array_size = pcp_result_slot_count(pcpResInfo); + if (verbose) { - frmt = "Database : %s\n" + frmt = "Database : %s\n" "Username : %s\n" "Start time : %s\n" "Creation time: %s\n" @@ -580,19 +584,20 @@ output_procinfo_result(PCPResultInfo* pcpResInfo, bool all, bool verbose) for (i = 0; i < array_size; i++) { - ProcessInfo *process_info = (ProcessInfo*) pcp_get_binary_data(pcpResInfo, i); - if(process_info == NULL) + ProcessInfo *process_info = (ProcessInfo *) pcp_get_binary_data(pcpResInfo, i); + + if (process_info == NULL) break; if ((!all) && (process_info->connection_info->database[0] == '\0')) continue; printed = true; *strcreatetime = *strstarttime = '\0'; - + if (process_info->start_time) strftime(strstarttime, 128, "%Y-%m-%d %H:%M:%S", localtime(&process_info->start_time)); if (process_info->connection_info->create_time) strftime(strcreatetime, 128, "%Y-%m-%d %H:%M:%S", localtime(&process_info->connection_info->create_time)); - + printf(frmt, process_info->connection_info->database, process_info->connection_info->user, @@ -606,18 +611,20 @@ output_procinfo_result(PCPResultInfo* pcpResInfo, bool all, bool verbose) process_info->pid, process_info->connection_info->backend_id); } - if(printed == false) + if (printed == false) printf("No process information available\n\n"); } static void -output_watchdog_info_result(PCPResultInfo* pcpResInfo, bool verbose) +output_watchdog_info_result(PCPResultInfo * pcpResInfo, bool verbose) { - int i; - PCPWDClusterInfo *cluster = (PCPWDClusterInfo *)pcp_get_binary_data(pcpResInfo,0); + int i; + PCPWDClusterInfo *cluster = (PCPWDClusterInfo *) pcp_get_binary_data(pcpResInfo, 0); + if (verbose) { - char* quorumStatus; + char *quorumStatus; + if (cluster->quorumStatus == 0) quorumStatus = "QUORUM IS ON THE EDGE"; else if (cluster->quorumStatus == 1) @@ -630,39 +637,41 @@ output_watchdog_info_result(PCPResultInfo* pcpResInfo, bool verbose) quorumStatus = "UNKNOWN"; printf("Watchdog Cluster Information \n"); - printf("Total Nodes : %d\n",cluster->remoteNodeCount +1); - printf("Remote Nodes : %d\n",cluster->remoteNodeCount); - printf("Quorum state : %s\n",quorumStatus); - printf("Alive Remote Nodes : %d\n",cluster->aliveNodeCount); - printf("VIP up on local node : %s\n",cluster->escalated?"YES":"NO"); - printf("Master Node Name : %s\n",cluster->masterNodeName); - printf("Master Host Name : %s\n\n",cluster->masterHostName); + printf("Total Nodes : %d\n", cluster->remoteNodeCount + 1); + printf("Remote Nodes : %d\n", cluster->remoteNodeCount); + printf("Quorum state : %s\n", quorumStatus); + printf("Alive Remote Nodes : %d\n", cluster->aliveNodeCount); + printf("VIP up on local node : %s\n", cluster->escalated ? "YES" : "NO"); + printf("Master Node Name : %s\n", cluster->masterNodeName); + printf("Master Host Name : %s\n\n", cluster->masterHostName); printf("Watchdog Node Information \n"); - for (i=0; i< cluster->nodeCount; i++) + for (i = 0; i < cluster->nodeCount; i++) { - PCPWDNodeInfo* watchdog_info = &cluster->nodeList[i]; - printf("Node Name : %s\n",watchdog_info->nodeName); - printf("Host Name : %s\n",watchdog_info->hostName); - printf("Delegate IP : %s\n",watchdog_info->delegate_ip); - printf("Pgpool port : %d\n",watchdog_info->pgpool_port); - printf("Watchdog port : %d\n",watchdog_info->wd_port); - printf("Node priority : %d\n",watchdog_info->wd_priority); - printf("Status : %d\n",watchdog_info->state); - printf("Status Name : %s\n\n",watchdog_info->stateName); + PCPWDNodeInfo *watchdog_info = &cluster->nodeList[i]; + + printf("Node Name : %s\n", watchdog_info->nodeName); + printf("Host Name : %s\n", watchdog_info->hostName); + printf("Delegate IP : %s\n", watchdog_info->delegate_ip); + printf("Pgpool port : %d\n", watchdog_info->pgpool_port); + printf("Watchdog port : %d\n", watchdog_info->wd_port); + printf("Node priority : %d\n", watchdog_info->wd_priority); + printf("Status : %d\n", watchdog_info->state); + printf("Status Name : %s\n\n", watchdog_info->stateName); } } else { printf("%d %s %s %s\n\n", - cluster->remoteNodeCount +1, - cluster->escalated?"YES":"NO", + cluster->remoteNodeCount + 1, + cluster->escalated ? "YES" : "NO", cluster->masterNodeName, cluster->masterHostName); - for (i=0; i< cluster->nodeCount; i++) + for (i = 0; i < cluster->nodeCount; i++) { - PCPWDNodeInfo* watchdog_info = &cluster->nodeList[i]; + PCPWDNodeInfo *watchdog_info = &cluster->nodeList[i]; + printf("%s %s %d %d %d %s\n", watchdog_info->nodeName, watchdog_info->hostName, @@ -678,25 +687,26 @@ output_watchdog_info_result(PCPResultInfo* pcpResInfo, bool verbose) static inline bool app_require_nodeID(void) { - return(current_app_type->app_type == PCP_ATTACH_NODE || - current_app_type->app_type == PCP_DETACH_NODE || - current_app_type->app_type == PCP_NODE_INFO || - current_app_type->app_type == PCP_PROMOTE_NODE || - current_app_type->app_type == PCP_RECOVERY_NODE); + return (current_app_type->app_type == PCP_ATTACH_NODE || + current_app_type->app_type == PCP_DETACH_NODE || + current_app_type->app_type == PCP_NODE_INFO || + current_app_type->app_type == PCP_PROMOTE_NODE || + current_app_type->app_type == PCP_RECOVERY_NODE); } static void usage(void) { - fprintf(stderr, "%s - %s\n",progname,current_app_type->description); + fprintf(stderr, "%s - %s\n", progname, current_app_type->description); fprintf(stderr, "Usage:\n"); - fprintf(stderr, "%s [OPTION...] %s\n",progname, - app_require_nodeID()?"[node-id]": - (current_app_type->app_type == PCP_WATCHDOG_INFO)?"[watchdog-id]": - (current_app_type->app_type == PCP_PROC_INFO)?"[process-id]":""); + fprintf(stderr, "%s [OPTION...] %s\n", progname, + app_require_nodeID() ? "[node-id]" : + (current_app_type->app_type == PCP_WATCHDOG_INFO) ? "[watchdog-id]" : + (current_app_type->app_type == PCP_PROC_INFO) ? "[process-id]" : ""); fprintf(stderr, "Options:\n"); + /* * print the command options */ @@ -705,6 +715,7 @@ usage(void) fprintf(stderr, " -p, --port=PORT PCP port number\n"); fprintf(stderr, " -w, --no-password never prompt for password\n"); fprintf(stderr, " -W, --password force password prompt (should happen automatically)\n"); + /* * Now the options not available for all utilities */ @@ -749,14 +760,14 @@ const char * get_progname(const char *argv0) { const char *nodir_name; - char *progname; - + char *progname; + nodir_name = last_dir_separator(argv0); if (nodir_name) nodir_name++; else nodir_name = argv0; - + /* * Make a copy in case argv[0] is modified by ps_status. Leaks memory, but * called only once. @@ -765,9 +776,9 @@ get_progname(const char *argv0) if (progname == NULL) { fprintf(stderr, "%s: out of memory\n", nodir_name); - exit(1); /* This could exit the postmaster */ + exit(1); /* This could exit the postmaster */ } - + return progname; } @@ -775,11 +786,13 @@ get_progname(const char *argv0) * Translate the BACKEND_STATUS enum value to string. * the function returns the constant string so should not be freed */ -static char* backend_status_to_string(BackendInfo *bi) +static char * +backend_status_to_string(BackendInfo * bi) { - char *statusName; + char *statusName; - switch (bi->backend_status) { + switch (bi->backend_status) + { case CON_UNUSED: statusName = BACKEND_STATUS_CON_UNUSED; @@ -794,12 +807,12 @@ static char* backend_status_to_string(BackendInfo *bi) break; case CON_DOWN: - { - if (bi->quarantine) - statusName = BACKEND_STATUS_QUARANTINE; - else - statusName = BACKEND_STATUS_CON_DOWN; - } + { + if (bi->quarantine) + statusName = BACKEND_STATUS_QUARANTINE; + else + statusName = BACKEND_STATUS_CON_DOWN; + } break; default: @@ -810,9 +823,11 @@ static char* backend_status_to_string(BackendInfo *bi) } /* Convert enum role to string */ -char *role_to_str(SERVER_ROLE role) +char * +role_to_str(SERVER_ROLE role) { static char *role_str[] = {"master", "slave", "primary", "standby"}; + if (role < ROLE_MASTER || role > ROLE_STANDBY) return "unknown"; return role_str[role]; diff --git a/src/tools/pgenc/pg_enc.c b/src/tools/pgenc/pg_enc.c index a9c4cd94f..12c2361f5 100644 --- a/src/tools/pgenc/pg_enc.c +++ b/src/tools/pgenc/pg_enc.c @@ -45,8 +45,8 @@ #define MAX_ENCODED_PASSWD_LEN (MAX_POOL_KEY_LEN * 2) -static void print_usage(const char prog[], int exit_code); -static void set_tio_attr(int enable); +static void print_usage(const char prog[], int exit_code); +static void set_tio_attr(int enable); static void update_pool_passwd(char *conf_file, char *username, char *password, char *key); static bool get_pool_key_filename(char *poolKeyFile); @@ -55,17 +55,17 @@ main(int argc, char *argv[]) { #define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code) - char conf_file[POOLMAXPATHLEN+1]; - char enc_key[MAX_POOL_KEY_LEN+1]; - char pg_pass[MAX_PGPASS_LEN+1]; - char username[MAX_USER_NAME_LEN+1]; - char key_file_path[POOLMAXPATHLEN]; - int opt; - int optindex; - bool updatepasswd = false; - bool prompt = false; - bool prompt_for_key = false; - char *pool_key = NULL; + char conf_file[POOLMAXPATHLEN + 1]; + char enc_key[MAX_POOL_KEY_LEN + 1]; + char pg_pass[MAX_PGPASS_LEN + 1]; + char username[MAX_USER_NAME_LEN + 1]; + char key_file_path[POOLMAXPATHLEN]; + int opt; + int optindex; + bool updatepasswd = false; + bool prompt = false; + bool prompt_for_key = false; + char *pool_key = NULL; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -81,8 +81,9 @@ main(int argc, char *argv[]) snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); - /* initialize username buffer with zeros so that we can use strlen on it later - to check if a username was given on the command line + /* + * initialize username buffer with zeros so that we can use strlen on it + * later to check if a username was given on the command line */ memset(username, 0, sizeof(username)); memset(enc_key, 0, sizeof(enc_key)); @@ -92,19 +93,19 @@ main(int argc, char *argv[]) { switch (opt) { - case 'p': /* prompt for postgres password */ + case 'p': /* prompt for postgres password */ prompt = true; break; - case 'P': /* prompt for encryption key */ + case 'P': /* prompt for encryption key */ prompt_for_key = true; break; - case 'm': /* update password file */ + case 'm': /* update password file */ updatepasswd = true; break; - case 'f': /* specify configuration file */ + case 'f': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); @@ -112,7 +113,8 @@ main(int argc, char *argv[]) strlcpy(conf_file, optarg, sizeof(conf_file)); break; - case 'k': /* specify key file for encrypting pool_password entries */ + case 'k': /* specify key file for encrypting + * pool_password entries */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); @@ -120,7 +122,7 @@ main(int argc, char *argv[]) strlcpy(key_file_path, optarg, sizeof(key_file_path)); break; - case 'K': /* specify configuration file */ + case 'K': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); @@ -151,14 +153,14 @@ main(int argc, char *argv[]) /* Prompt for password. */ if (prompt || optind >= argc) { - char buf[MAX_PGPASS_LEN]; - int len; + char buf[MAX_PGPASS_LEN]; + int len; set_tio_attr(1); printf("db password: "); if (!fgets(buf, sizeof(buf), stdin)) { - int eno = errno; + int eno = errno; fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); @@ -170,40 +172,41 @@ main(int argc, char *argv[]) /* Remove LF at the end of line, if there is any. */ len = strlen(buf); - if (len > 0 && buf[len-1] == '\n') + if (len > 0 && buf[len - 1] == '\n') { - buf[len-1] = '\0'; + buf[len - 1] = '\0'; len--; } - stpncpy(pg_pass,buf,sizeof(pg_pass)); + stpncpy(pg_pass, buf, sizeof(pg_pass)); } /* Read password from argv. */ else { - int len; + int len; len = strlen(argv[optind]); if (len > MAX_PGPASS_LEN) { - fprintf(stderr, "Error: Input exceeds maximum password length given:%d max allowed:%d!\n\n",len,MAX_PGPASS_LEN); + fprintf(stderr, "Error: Input exceeds maximum password length given:%d max allowed:%d!\n\n", len, MAX_PGPASS_LEN); PRINT_USAGE(EXIT_FAILURE); } - stpncpy(pg_pass,argv[optind],sizeof(pg_pass)); + stpncpy(pg_pass, argv[optind], sizeof(pg_pass)); } /* prompt for key, overrides all key related arguments */ if (prompt_for_key) { - char buf[MAX_POOL_KEY_LEN]; - int len; + char buf[MAX_POOL_KEY_LEN]; + int len; + /* we need to read the encryption key from stdin */ set_tio_attr(1); printf("encryption key: "); if (!fgets(buf, sizeof(buf), stdin)) { - int eno = errno; + int eno = errno; fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); @@ -214,9 +217,9 @@ main(int argc, char *argv[]) set_tio_attr(0); /* Remove LF at the end of line, if there is any. */ len = strlen(buf); - if (len > 0 && buf[len-1] == '\n') + if (len > 0 && buf[len - 1] == '\n') { - buf[len-1] = '\0'; + buf[len - 1] = '\0'; len--; } if (len == 0) @@ -224,7 +227,7 @@ main(int argc, char *argv[]) fprintf(stderr, "encryption key not provided\n"); exit(EXIT_FAILURE); } - stpncpy(enc_key,buf,sizeof(enc_key)); + stpncpy(enc_key, buf, sizeof(enc_key)); } else { @@ -237,7 +240,7 @@ main(int argc, char *argv[]) get_pool_key_filename(key_file_path); } - fprintf(stdout, "trying to read key from file %s\n",key_file_path); + fprintf(stdout, "trying to read key from file %s\n", key_file_path); pool_key = read_pool_key(key_file_path); } @@ -261,21 +264,22 @@ main(int argc, char *argv[]) { unsigned char ciphertext[MAX_ENCODED_PASSWD_LEN]; unsigned char b64_enc[MAX_ENCODED_PASSWD_LEN]; - int len; - int cypher_len; + int len; + int cypher_len; - cypher_len = aes_encrypt_with_password((unsigned char*)pg_pass, - strlen(pg_pass), pool_key, ciphertext); + cypher_len = aes_encrypt_with_password((unsigned char *) pg_pass, + strlen(pg_pass), pool_key, ciphertext); /* generate the hash for the given username */ - len = pg_b64_encode((const char*)ciphertext, cypher_len, (char*)b64_enc); + len = pg_b64_encode((const char *) ciphertext, cypher_len, (char *) b64_enc); b64_enc[len] = 0; - fprintf(stdout,"\n%s\n",b64_enc); - fprintf(stdout,"pool_passwd string: AES%s\n",b64_enc); + fprintf(stdout, "\n%s\n", b64_enc); + fprintf(stdout, "pool_passwd string: AES%s\n", b64_enc); #ifdef DEBUG_ENCODING unsigned char b64_dec[MAX_ENCODED_PASSWD_LEN]; unsigned char plaintext[MAX_PGPASS_LEN]; + len = pg_b64_decode(b64_enc, len, b64_dec); len = aes_decrypt_with_password(b64_dec, len, pool_key, plaintext); @@ -289,17 +293,18 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } -static void update_pool_passwd(char *conf_file, char *username, char *password, char *key) +static void +update_pool_passwd(char *conf_file, char *username, char *password, char *key) { struct passwd *pw; - char pool_passwd[MAX_PGPASS_LEN+1]; - char dirnamebuf[POOLMAXPATHLEN+1]; - char *dirp; - char *user = username; + char pool_passwd[MAX_PGPASS_LEN + 1]; + char dirnamebuf[POOLMAXPATHLEN + 1]; + char *dirp; + char *user = username; unsigned char ciphertext[MAX_ENCODED_PASSWD_LEN]; unsigned char b64_enc[MAX_ENCODED_PASSWD_LEN]; - int len; + int len; if (pool_init_config()) { @@ -318,7 +323,7 @@ static void update_pool_passwd(char *conf_file, char *username, char *password, dirp, pool_config->pool_passwd); pool_init_pool_passwd(pool_passwd, POOL_PASSWD_RW); - if(username == NULL || strlen(username) == 0) + if (username == NULL || strlen(username) == 0) { /* get the user information from the current uid */ pw = getpwuid(getuid()); @@ -331,44 +336,46 @@ static void update_pool_passwd(char *conf_file, char *username, char *password, } /* generate the hash for the given username */ - int cypher_len = aes_encrypt_with_password((unsigned char*)password, strlen(password), key, ciphertext); - if (cypher_len <= 0 ) + int cypher_len = aes_encrypt_with_password((unsigned char *) password, strlen(password), key, ciphertext); + + if (cypher_len <= 0) { fprintf(stderr, "password encryption failed\n\n"); exit(EXIT_FAILURE); } /* copy the prefix at the start of string */ - strcpy((char*)b64_enc, (char*)PASSWORD_AES_PREFIX); - len = pg_b64_encode((const char*)ciphertext, cypher_len, (char*)b64_enc + strlen(PASSWORD_AES_PREFIX)); - if (cypher_len <= 0 ) + strcpy((char *) b64_enc, (char *) PASSWORD_AES_PREFIX); + len = pg_b64_encode((const char *) ciphertext, cypher_len, (char *) b64_enc + strlen(PASSWORD_AES_PREFIX)); + if (cypher_len <= 0) { fprintf(stderr, "base64 encoding failed\n\n"); exit(EXIT_FAILURE); } - len+= strlen(PASSWORD_AES_PREFIX); + len += strlen(PASSWORD_AES_PREFIX); b64_enc[len] = 0; - pool_create_passwdent(user, (char*)b64_enc); + pool_create_passwdent(user, (char *) b64_enc); pool_finish_pool_passwd(); } static void print_usage(const char prog[], int exit_code) { - char homedir[POOLMAXPATHLEN]; - FILE *stream = (exit_code == EXIT_SUCCESS) ? stdout : stderr; + char homedir[POOLMAXPATHLEN]; + FILE *stream = (exit_code == EXIT_SUCCESS) ? stdout : stderr; + if (!get_home_directory(homedir, sizeof(homedir))) - strncpy(homedir,"USER-HOME-DIR",POOLMAXPATHLEN); + strncpy(homedir, "USER-HOME-DIR", POOLMAXPATHLEN); - fprintf(stream, "%s version %s (%s),\n", PACKAGE, VERSION, PGPOOLVERSION); + fprintf(stream, "%s version %s (%s),\n", PACKAGE, VERSION, PGPOOLVERSION); fprintf(stream, " password encryption utility for Pgpool\n\n"); fprintf(stream, "Usage:\n"); - fprintf(stream, " %s [OPTIONS] <PASSWORD>\n",prog); + fprintf(stream, " %s [OPTIONS] <PASSWORD>\n", prog); fprintf(stream, " -k, --key-file=KEY_FILE\n"); fprintf(stream, " Set the path to the encryption key file.\n"); - fprintf(stream, " Default: %s/%s\n",homedir, POOLKEYFILE); - fprintf(stream, " Can be overridden by the %s environment variable.\n",POOLKEYFILEENV); + fprintf(stream, " Default: %s/%s\n", homedir, POOLKEYFILE); + fprintf(stream, " Can be overridden by the %s environment variable.\n", POOLKEYFILEENV); fprintf(stream, " -K, --enc-key=ENCRYPTION_KEY\n"); fprintf(stream, " Encryption key to be used for encrypting database passwords.\n"); fprintf(stream, " -f, --config-file=CONFIG_FILE\n"); @@ -406,8 +413,8 @@ set_tio_attr(int set) tio_save = tio; - tio.c_iflag &= ~(BRKINT|ISTRIP|IXON); - tio.c_lflag &= ~(ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHONL); + tio.c_iflag &= ~(BRKINT | ISTRIP | IXON); + tio.c_lflag &= ~(ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; @@ -430,7 +437,7 @@ set_tio_attr(int set) static bool get_pool_key_filename(char *poolKeyFile) { - char *passfile_env; + char *passfile_env; if ((passfile_env = getenv(POOLKEYFILEENV)) != NULL) { @@ -439,11 +446,11 @@ get_pool_key_filename(char *poolKeyFile) } else { - char homedir[POOLMAXPATHLEN]; + char homedir[POOLMAXPATHLEN]; + if (!get_home_directory(homedir, sizeof(homedir))) return false; snprintf(poolKeyFile, POOLMAXPATHLEN, "%s/%s", homedir, POOLKEYFILE); } return true; } - diff --git a/src/tools/pgmd5/pg_md5.c b/src/tools/pgmd5/pg_md5.c index 7c123ba4d..cf37e890a 100644 --- a/src/tools/pgmd5/pg_md5.c +++ b/src/tools/pgmd5/pg_md5.c @@ -43,8 +43,8 @@ /* Maximum number of characters allowed for input. */ #define MAX_INPUT_SIZE MAX_USER_NAME_LEN -static void print_usage(const char prog[], int exit_code); -static void set_tio_attr(int enable); +static void print_usage(const char prog[], int exit_code); +static void set_tio_attr(int enable); static void update_pool_passwd(char *conf_file, char *username, char *password); int @@ -52,12 +52,12 @@ main(int argc, char *argv[]) { #define PRINT_USAGE(exit_code) print_usage(argv[0], exit_code) - char conf_file[POOLMAXPATHLEN+1]; - char username[MAX_INPUT_SIZE+1]; - int opt; - int optindex; - bool md5auth = false; - bool prompt = false; + char conf_file[POOLMAXPATHLEN + 1]; + char username[MAX_INPUT_SIZE + 1]; + int opt; + int optindex; + bool md5auth = false; + bool prompt = false; static struct option long_options[] = { {"help", no_argument, NULL, 'h'}, @@ -70,24 +70,25 @@ main(int argc, char *argv[]) snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); - /* initialize username buffer with zeros so that we can use strlen on it later - to check if a username was given on the command line + /* + * initialize username buffer with zeros so that we can use strlen on it + * later to check if a username was given on the command line */ - memset(username, 0, MAX_INPUT_SIZE+1); + memset(username, 0, MAX_INPUT_SIZE + 1); - while ((opt = getopt_long(argc, argv, "hpmf:u:", long_options, &optindex)) != -1) + while ((opt = getopt_long(argc, argv, "hpmf:u:", long_options, &optindex)) != -1) { switch (opt) { - case 'p': /* prompt for password */ + case 'p': /* prompt for password */ prompt = true; break; - case 'm': /* produce md5 authentication password */ + case 'm': /* produce md5 authentication password */ md5auth = true; break; - case 'f': /* specify configuration file */ + case 'f': /* specify configuration file */ if (!optarg) { PRINT_USAGE(EXIT_SUCCESS); @@ -113,20 +114,20 @@ main(int argc, char *argv[]) PRINT_USAGE(EXIT_SUCCESS); break; } - } + } /* Prompt for password. */ if (prompt) { - char md5[MD5_PASSWD_LEN+1]; - char buf[MAX_INPUT_SIZE+1]; - int len; + char md5[MD5_PASSWD_LEN + 1]; + char buf[MAX_INPUT_SIZE + 1]; + int len; set_tio_attr(1); printf("password: "); - if (!fgets(buf, (MAX_INPUT_SIZE+1), stdin)) + if (!fgets(buf, (MAX_INPUT_SIZE + 1), stdin)) { - int eno = errno; + int eno = errno; fprintf(stderr, "Couldn't read input from stdin. (fgets(): %s)", strerror(eno)); @@ -138,9 +139,9 @@ main(int argc, char *argv[]) /* Remove LF at the end of line, if there is any. */ len = strlen(buf); - if (len > 0 && buf[len-1] == '\n') + if (len > 0 && buf[len - 1] == '\n') { - buf[len-1] = '\0'; + buf[len - 1] = '\0'; len--; } @@ -158,14 +159,14 @@ main(int argc, char *argv[]) /* Read password from argv. */ else { - char md5[POOL_PASSWD_LEN+1]; - int len; + char md5[POOL_PASSWD_LEN + 1]; + int len; if (optind >= argc) { PRINT_USAGE(EXIT_FAILURE); } - + len = strlen(argv[optind]); if (len > MAX_INPUT_SIZE) @@ -188,13 +189,14 @@ main(int argc, char *argv[]) return EXIT_SUCCESS; } -static void update_pool_passwd(char *conf_file, char *username, char *password) +static void +update_pool_passwd(char *conf_file, char *username, char *password) { struct passwd *pw; - char md5[POOL_PASSWD_LEN+1]; - char pool_passwd[POOLMAXPATHLEN+1]; - char dirnamebuf[POOLMAXPATHLEN+1]; - char *dirp; + char md5[POOL_PASSWD_LEN + 1]; + char pool_passwd[POOLMAXPATHLEN + 1]; + char dirnamebuf[POOLMAXPATHLEN + 1]; + char *dirp; if (pool_init_config()) { @@ -283,8 +285,8 @@ set_tio_attr(int set) tio_save = tio; - tio.c_iflag &= ~(BRKINT|ISTRIP|IXON); - tio.c_lflag &= ~(ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHONL); + tio.c_iflag &= ~(BRKINT | ISTRIP | IXON); + tio.c_lflag &= ~(ICANON | IEXTEN | ECHO | ECHOE | ECHOK | ECHONL); tio.c_cc[VMIN] = 1; tio.c_cc[VTIME] = 0; diff --git a/src/tools/pgproto/buffer.c b/src/tools/pgproto/buffer.c index 95f9a8ba6..173bfec10 100644 --- a/src/tools/pgproto/buffer.c +++ b/src/tools/pgproto/buffer.c @@ -32,17 +32,18 @@ * the data is returned to "bufp". If the format is not follows above, exit * within this function. */ -int buffer_read_int(char *buf, char **bufp) +int +buffer_read_int(char *buf, char **bufp) { - char intbuf[128]; - int i; - char *p; - int intval; - char *endptr; + char intbuf[128]; + int i; + char *p; + int intval; + char *endptr; p = intbuf; - for (i=0;i<sizeof(intbuf)-1;i++) + for (i = 0; i < sizeof(intbuf) - 1; i++) { if (*buf == '\t') break; @@ -71,10 +72,12 @@ int buffer_read_int(char *buf, char **bufp) * afer reading the data is returned to "bufp". If the format is not follows * above, exit within this function. */ -char *buffer_read_string(char *buf, char **bufp) +char * +buffer_read_string(char *buf, char **bufp) { - int len; - char *p, *str; + int len; + char *p, + *str; if (*buf != '"') { @@ -85,7 +88,7 @@ char *buffer_read_string(char *buf, char **bufp) buf++; len = strlen(buf); - p = str = pg_malloc(len+1); + p = str = pg_malloc(len + 1); do { @@ -100,7 +103,7 @@ char *buffer_read_string(char *buf, char **bufp) if (p == str || *(p - 1) != '"') { - fprintf(stderr, "buffer_read_string: given string does not end with \"(%c)", p==str?' ':*(p-1)); + fprintf(stderr, "buffer_read_string: given string does not end with \"(%c)", p == str ? ' ' : *(p - 1)); exit(1); } @@ -117,9 +120,10 @@ char *buffer_read_string(char *buf, char **bufp) * reading the data is returned to "bufp". If the format is not follows * above, exit within this function. */ -char buffer_read_char(char *buf, char **bufp) +char +buffer_read_char(char *buf, char **bufp) { - char c; + char c; if (*buf != '\'') { diff --git a/src/tools/pgproto/buffer.h b/src/tools/pgproto/buffer.h index e632406dc..087798c23 100644 --- a/src/tools/pgproto/buffer.h +++ b/src/tools/pgproto/buffer.h @@ -19,7 +19,7 @@ #define SKIP_TABS(p) while (*p == '\t') {p++;} -extern int buffer_read_int(char *buf, char **bufp); +extern int buffer_read_int(char *buf, char **bufp); extern char *buffer_read_string(char *buf, char **bufp); extern char buffer_read_char(char *buf, char **bufp); diff --git a/src/tools/pgproto/extended_query.c b/src/tools/pgproto/extended_query.c index bc6781ec1..753df958d 100644 --- a/src/tools/pgproto/extended_query.c +++ b/src/tools/pgproto/extended_query.c @@ -35,15 +35,16 @@ * Send parse messae. "conn" should at the point right after the message kind * was read. */ -void process_parse(char *buf, PGconn *conn) +void +process_parse(char *buf, PGconn *conn) { - char *query; - int len; - char *stmt; - short noids; - int oids[MAXENTRIES]; - int i; - char *bufp; + char *query; + int len; + char *stmt; + short noids; + int oids[MAXENTRIES]; + int i; + char *bufp; SKIP_TABS(buf); @@ -51,13 +52,13 @@ void process_parse(char *buf, PGconn *conn) stmt = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(stmt)+1; + len += strlen(stmt) + 1; SKIP_TABS(buf); query = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(query)+1; + len += strlen(query) + 1; SKIP_TABS(buf); @@ -72,13 +73,13 @@ void process_parse(char *buf, PGconn *conn) exit(1); } - len += sizeof(short) + noids*sizeof(int); + len += sizeof(short) + noids * sizeof(int); if (noids > 0) { fprintf(stderr, ", oids={"); - for (i=0;i<noids;i++) + for (i = 0; i < noids; i++) { oids[i] = buffer_read_int(buf, &bufp); fprintf(stderr, "%d", oids[i]); @@ -96,7 +97,7 @@ void process_parse(char *buf, PGconn *conn) send_int16(noids, conn); if (noids > 0) { - for (i=0;i<noids;i++) + for (i = 0; i < noids; i++) { send_int(oids[i], conn); } @@ -107,20 +108,21 @@ void process_parse(char *buf, PGconn *conn) * Send bind messae. "conn" should be at the point right after the message kind * was read. */ -void process_bind(char *buf, PGconn *conn) +void +process_bind(char *buf, PGconn *conn) { - int len; - char *stmt; - char *portal; - short nparams; - short ncodes; - short codes[MAXENTRIES]; - int paramlens[MAXENTRIES]; - char *paramvals[MAXENTRIES]; - short nresult_formatcodes; - short result_formatcodes[MAXENTRIES]; - int i; - char *bufp; + int len; + char *stmt; + char *portal; + short nparams; + short ncodes; + short codes[MAXENTRIES]; + int paramlens[MAXENTRIES]; + char *paramvals[MAXENTRIES]; + short nresult_formatcodes; + short result_formatcodes[MAXENTRIES]; + int i; + char *bufp; SKIP_TABS(buf); @@ -128,20 +130,20 @@ void process_bind(char *buf, PGconn *conn) portal = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(portal)+1; + len += strlen(portal) + 1; SKIP_TABS(buf); stmt = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(stmt)+1; + len += strlen(stmt) + 1; fprintf(stderr, "FE=> Bind(stmt=\"%s\", portal=\"%s\")", stmt, portal); SKIP_TABS(buf); ncodes = buffer_read_int(buf, &bufp); - len += sizeof(short) + sizeof(short)*ncodes; + len += sizeof(short) + sizeof(short) * ncodes; buf = bufp; SKIP_TABS(buf); @@ -154,7 +156,7 @@ void process_bind(char *buf, PGconn *conn) if (ncodes > 0) { - for (i=0;i<ncodes;i++) + for (i = 0; i < ncodes; i++) { codes[i] = buffer_read_int(buf, &bufp); buf = bufp; @@ -163,7 +165,7 @@ void process_bind(char *buf, PGconn *conn) } nparams = buffer_read_int(buf, &bufp); - len += sizeof(short) + sizeof(short)*nparams; + len += sizeof(short) + sizeof(short) * nparams; buf = bufp; SKIP_TABS(buf); @@ -173,7 +175,7 @@ void process_bind(char *buf, PGconn *conn) exit(1); } - for (i=0;i<nparams;i++) + for (i = 0; i < nparams; i++) { paramlens[i] = buffer_read_int(buf, &bufp); len += sizeof(int); @@ -192,12 +194,12 @@ void process_bind(char *buf, PGconn *conn) nresult_formatcodes = buffer_read_int(buf, &bufp); buf = bufp; - len += sizeof(short) + sizeof(short)*nresult_formatcodes; + len += sizeof(short) + sizeof(short) * nresult_formatcodes; SKIP_TABS(buf); if (nresult_formatcodes >= 2) { - for (i=0;i<nresult_formatcodes;i++) + for (i = 0; i < nresult_formatcodes; i++) { result_formatcodes[i] = buffer_read_int(buf, &bufp); buf = bufp; @@ -211,13 +213,13 @@ void process_bind(char *buf, PGconn *conn) send_string(portal, conn); send_string(stmt, conn); send_int16(ncodes, conn); - for (i=0;i<ncodes;i++) + for (i = 0; i < ncodes; i++) { send_int16(codes[i], conn); } send_int16(nparams, conn); - for (i=0;i<nparams;i++) + for (i = 0; i < nparams; i++) { if (paramlens[i] != -1) { @@ -233,7 +235,7 @@ void process_bind(char *buf, PGconn *conn) } send_int16(nresult_formatcodes, conn); - for (i=0;i<nresult_formatcodes;i++) + for (i = 0; i < nresult_formatcodes; i++) { send_int16(result_formatcodes[i], conn); } @@ -243,12 +245,13 @@ void process_bind(char *buf, PGconn *conn) * Send execute messae. "conn" should at the point right after the message * kind was read. */ -void process_execute(char *buf, PGconn *conn) +void +process_execute(char *buf, PGconn *conn) { - int len; - char *portal; - int maxrows; - char *bufp; + int len; + char *portal; + int maxrows; + char *bufp; SKIP_TABS(buf); @@ -256,7 +259,7 @@ void process_execute(char *buf, PGconn *conn) portal = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(portal)+1; + len += strlen(portal) + 1; SKIP_TABS(buf); @@ -278,12 +281,13 @@ void process_execute(char *buf, PGconn *conn) * Send describe messae. "conn" should at the point right after the message kind * was read. */ -void process_describe(char *buf, PGconn *conn) +void +process_describe(char *buf, PGconn *conn) { - char kind; - int len; - char *stmt; - char *bufp; + char kind; + int len; + char *stmt; + char *bufp; SKIP_TABS(buf); @@ -297,7 +301,7 @@ void process_describe(char *buf, PGconn *conn) stmt = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(stmt)+1; + len += strlen(stmt) + 1; SKIP_TABS(buf); @@ -325,12 +329,13 @@ void process_describe(char *buf, PGconn *conn) * Send close messae. "conn" should at the point right after the message kind * was read. */ -void process_close(char *buf, PGconn *conn) +void +process_close(char *buf, PGconn *conn) { - char kind; - int len; - char *stmt; - char *bufp; + char kind; + int len; + char *stmt; + char *bufp; SKIP_TABS(buf); @@ -344,7 +349,7 @@ void process_close(char *buf, PGconn *conn) stmt = buffer_read_string(buf, &bufp); buf = bufp; - len += strlen(stmt)+1; + len += strlen(stmt) + 1; SKIP_TABS(buf); diff --git a/src/tools/pgproto/fe_memutils.h b/src/tools/pgproto/fe_memutils.h index 117ce5b35..0167b968d 100644 --- a/src/tools/pgproto/fe_memutils.h +++ b/src/tools/pgproto/fe_memutils.h @@ -90,4 +90,4 @@ extern size_t pvsnprintf(char *buf, size_t len, const char *fmt, va_list args) p /* Get a bit mask of the bits set in non-long aligned addresses */ #define LONG_ALIGN_MASK (sizeof(long) - 1) -#endif /* FE_MEMUTILS_H */ +#endif /* FE_MEMUTILS_H */ diff --git a/src/tools/pgproto/main.c b/src/tools/pgproto/main.c index ef78e3101..5e6284522 100644 --- a/src/tools/pgproto/main.c +++ b/src/tools/pgproto/main.c @@ -36,26 +36,27 @@ static void usage(void); static FILE *openfile(char *filename); static PGconn *connect_db(char *host, char *port, char *user, char *database); static void read_and_process(FILE *fd, PGconn *conn); -static int process_a_line(char *buf, PGconn *con); -static int process_message_type(int kind, char *buf, PGconn *conn); +static int process_a_line(char *buf, PGconn *con); +static int process_message_type(int kind, char *buf, PGconn *conn); static void process_function_call(char *buf, PGconn *conn); -int read_nap = 0; +int read_nap = 0; -int main(int argc, char **argv) +int +main(int argc, char **argv) { - int opt; - int optindex; - char *env; - char *host = ""; - char *port = "5432"; - char *user = ""; - char *database = ""; - char *data_file = PGPROTODATA; - int debug = 0; - FILE *fd; - PGconn *con; - int var; + int opt; + int optindex; + char *env; + char *host = ""; + char *port = "5432"; + char *user = ""; + char *database = ""; + char *data_file = PGPROTODATA; + int debug = 0; + FILE *fd; + PGconn *con; + int var; static struct option long_options[] = { {"host", optional_argument, NULL, 'h'}, @@ -150,12 +151,14 @@ int main(int argc, char **argv) return 0; } -static void show_version(void) +static void +show_version(void) { - fprintf(stderr, "pgproto (%s) %s\n", PACKAGE, PACKAGE_VERSION); + fprintf(stderr, "pgproto (%s) %s\n", PACKAGE, PACKAGE_VERSION); } -static void usage(void) +static void +usage(void) { printf("Usage: %s\n" "-h, --hostname=HOSTNAME (default: UNIX domain socket)\n" @@ -167,16 +170,17 @@ static void usage(void) "-D, --debug\n" "-?, --help\n" "-v, --version\n", - PACKAGE); + PACKAGE); } /* * Open protocol data and return the file descriptor. If failed to open the * file, do not return and exit within this function. */ -static FILE *openfile(char *filename) +static FILE * +openfile(char *filename) { - FILE *fd = fopen(filename,"r"); + FILE *fd = fopen(filename, "r"); if (fd == NULL) { @@ -190,11 +194,12 @@ static FILE *openfile(char *filename) * Connect to the specifed PostgreSQL. If failed, do not return and exit * within this function. */ -static PGconn *connect_db(char *host, char *port, char *user, char *database) +static PGconn * +connect_db(char *host, char *port, char *user, char *database) { - char conninfo[1024]; - PGconn *conn; - size_t n; + char conninfo[1024]; + PGconn *conn; + size_t n; conninfo[0] = '\0'; n = sizeof(conninfo); @@ -203,7 +208,7 @@ static PGconn *connect_db(char *host, char *port, char *user, char *database) { n -= sizeof("host="); strncat(conninfo, "host=", n); - n -= strlen(host)+1; + n -= strlen(host) + 1; strncat(conninfo, host, n); } @@ -211,7 +216,7 @@ static PGconn *connect_db(char *host, char *port, char *user, char *database) { n -= sizeof("port="); strncat(conninfo, " port=", n); - n -= strlen(port)+1; + n -= strlen(port) + 1; strncat(conninfo, port, n); } @@ -219,7 +224,7 @@ static PGconn *connect_db(char *host, char *port, char *user, char *database) { n -= sizeof("user="); strncat(conninfo, " user=", n); - n -= strlen(user)+1; + n -= strlen(user) + 1; strcat(conninfo, user); } @@ -227,7 +232,7 @@ static PGconn *connect_db(char *host, char *port, char *user, char *database) { n -= sizeof("dbname="); strncat(conninfo, " dbname=", n); - n -= strlen(database)+1; + n -= strlen(database) + 1; strncat(conninfo, database, n); } @@ -245,15 +250,16 @@ static PGconn *connect_db(char *host, char *port, char *user, char *database) /* * Read the protocol data file and process it. */ -static void read_and_process(FILE *fd, PGconn *conn) +static void +read_and_process(FILE *fd, PGconn *conn) { #define PGPROTO_READBUF_LENGTH 8192 - int status; - char *buf; - int buflen; - char *p; - int len; - int readp; + int status; + char *buf; + int buflen; + char *p; + int len; + int readp; for (;;) { @@ -270,7 +276,10 @@ static void read_and_process(FILE *fd, PGconn *conn) exit(0); } - /* if ends with backslash + new line, assume it's a continuous line */ + /* + * if ends with backslash + new line, assume it's a continuous + * line + */ len = strlen(p); if (p[len - 2] != '\\' || p[len - 1] != '\n') { @@ -296,10 +305,11 @@ static void read_and_process(FILE *fd, PGconn *conn) /* * Process a line of protocol data. */ -static int process_a_line(char *buf, PGconn *conn) +static int +process_a_line(char *buf, PGconn *conn) { - char *p = buf; - int kind; + char *p = buf; + int kind; #ifdef DEBUG fprintf(stderr, "buf: %s", buf); @@ -324,7 +334,7 @@ static int process_a_line(char *buf, PGconn *conn) p++; - kind = (unsigned char)(*p++); + kind = (unsigned char) (*p++); if (*p != '\'') { @@ -342,18 +352,19 @@ static int process_a_line(char *buf, PGconn *conn) /* * Read a line of message from buf and process it. */ -static int process_message_type(int kind, char *buf, PGconn *conn) +static int +process_message_type(int kind, char *buf, PGconn *conn) { #ifdef DEBUG fprintf(stderr, "message kind is %c\n", kind); #endif - char *query; - char *err_msg; - char *data; - char *bufp; + char *query; + char *err_msg; + char *data; + char *bufp; - switch(kind) + switch (kind) { case 'Y': read_until_ready_for_query(conn, 0); @@ -365,19 +376,19 @@ static int process_message_type(int kind, char *buf, PGconn *conn) case 'X': fprintf(stderr, "FE=> Terminate\n"); - send_char((char)kind, conn); + send_char((char) kind, conn); send_int(sizeof(int), conn); break; case 'S': fprintf(stderr, "FE=> Sync\n"); - send_char((char)kind, conn); + send_char((char) kind, conn); send_int(sizeof(int), conn); break; case 'H': fprintf(stderr, "FE=> Flush\n"); - send_char((char)kind, conn); + send_char((char) kind, conn); send_int(sizeof(int), conn); break; @@ -385,8 +396,8 @@ static int process_message_type(int kind, char *buf, PGconn *conn) buf++; query = buffer_read_string(buf, &bufp); fprintf(stderr, "FE=> Query (query=\"%s\")\n", query); - send_char((char)kind, conn); - send_int(sizeof(int)+strlen(query)+1, conn); + send_char((char) kind, conn); + send_int(sizeof(int) + strlen(query) + 1, conn); send_string(query, conn); pg_free(query); break; @@ -395,15 +406,15 @@ static int process_message_type(int kind, char *buf, PGconn *conn) buf++; data = buffer_read_string(buf, &bufp); fprintf(stderr, "FE=> CopyData (copy data=\"%s\")\n", data); - send_char((char)kind, conn); - send_int(sizeof(int)+strlen(data), conn); + send_char((char) kind, conn); + send_int(sizeof(int) + strlen(data), conn); send_byte(data, strlen(data), conn); pg_free(data); break; case 'c': fprintf(stderr, "FE=> CopyDone\n"); - send_char((char)kind, conn); + send_char((char) kind, conn); send_int(sizeof(int), conn); break; @@ -411,8 +422,8 @@ static int process_message_type(int kind, char *buf, PGconn *conn) buf++; err_msg = buffer_read_string(buf, &bufp); fprintf(stderr, "FE=> CopyFail (error message=\"%s\")\n", err_msg); - send_char((char)kind, conn); - send_int(sizeof(int)+strlen(err_msg)+1, conn); + send_char((char) kind, conn); + send_int(sizeof(int) + strlen(err_msg) + 1, conn); send_string(err_msg, conn); pg_free(err_msg); break; @@ -451,18 +462,19 @@ static int process_message_type(int kind, char *buf, PGconn *conn) /* * Process function call messaage */ -static void process_function_call(char *buf, PGconn *conn) +static void +process_function_call(char *buf, PGconn *conn) { - int len; - int foid; - short nparams; - short ncodes; - short codes[MAXENTRIES]; - int paramlens[MAXENTRIES]; - char *paramvals[MAXENTRIES]; - short result_formatcode; - int i; - char *bufp; + int len; + int foid; + short nparams; + short ncodes; + short codes[MAXENTRIES]; + int paramlens[MAXENTRIES]; + char *paramvals[MAXENTRIES]; + short result_formatcode; + int i; + char *bufp; SKIP_TABS(buf); @@ -477,7 +489,7 @@ static void process_function_call(char *buf, PGconn *conn) /* number of argument format codes */ ncodes = buffer_read_int(buf, &bufp); - len += sizeof(short) + sizeof(short)*ncodes; + len += sizeof(short) + sizeof(short) * ncodes; buf = bufp; SKIP_TABS(buf); @@ -491,7 +503,7 @@ static void process_function_call(char *buf, PGconn *conn) /* read each format code */ if (ncodes > 0) { - for (i=0;i<ncodes;i++) + for (i = 0; i < ncodes; i++) { codes[i] = buffer_read_int(buf, &bufp); buf = bufp; @@ -512,7 +524,7 @@ static void process_function_call(char *buf, PGconn *conn) } /* read each function argument */ - for (i=0;i<nparams;i++) + for (i = 0; i < nparams; i++) { paramlens[i] = buffer_read_int(buf, &bufp); len += sizeof(int); @@ -546,16 +558,16 @@ static void process_function_call(char *buf, PGconn *conn) fprintf(stderr, "\n"); send_char('F', conn); - send_int(len, conn); /* message length */ - send_int(foid, conn); /* function oid */ + send_int(len, conn); /* message length */ + send_int(foid, conn); /* function oid */ send_int16(ncodes, conn); /* number of argument format code */ - for (i=0;i<ncodes;i++) /* argument format codes */ + for (i = 0; i < ncodes; i++) /* argument format codes */ { send_int16(codes[i], conn); } send_int16(nparams, conn); /* number of function arguments */ - for (i=0;i<nparams;i++) /* function arguments */ + for (i = 0; i < nparams; i++) /* function arguments */ { send_int(paramlens[i], conn); /* argument length */ diff --git a/src/tools/pgproto/pgproto.h b/src/tools/pgproto/pgproto.h index da3253e91..9be981572 100644 --- a/src/tools/pgproto/pgproto.h +++ b/src/tools/pgproto/pgproto.h @@ -27,13 +27,14 @@ * Protocol data representation read from the data file. * We assume that the protocol version is V3. */ -typedef struct { - char type; /* message type */ - int size; /* message length excluding this (in host order) */ - char message[1]; /* actual message (variable length) */ -} PROTO_DATA; +typedef struct +{ + char type; /* message type */ + int size; /* message length excluding this (in host + * order) */ + char message[1]; /* actual message (variable length) */ +} PROTO_DATA; -extern int read_nap; - -#endif /* PGPROTO_H */ +extern int read_nap; +#endif /* PGPROTO_H */ diff --git a/src/tools/pgproto/read.c b/src/tools/pgproto/read.c index 3fefbff5a..1d8dd4d5c 100644 --- a/src/tools/pgproto/read.c +++ b/src/tools/pgproto/read.c @@ -28,29 +28,30 @@ #include "read.h" static char read_char(PGconn *conn); -static int read_int32(PGconn *conn); -static int read_int16(PGconn *conn); +static int read_int32(PGconn *conn); +static int read_int16(PGconn *conn); static char *read_bytes(int len, PGconn *conn); static void read_and_discard(PGconn *conn); -static void read_it(PGconn *conn, char * buf, int len); +static void read_it(PGconn *conn, char *buf, int len); /* * Read message from connection until ready for query message is received. If * a positive timeout is given, wait for timeout seconds then return if no * data is availble from the connection. */ -void read_until_ready_for_query(PGconn *conn, int timeout) +void +read_until_ready_for_query(PGconn *conn, int timeout) { - int kind; - int len; - char *buf; - char c; - char *p; - int fd; - int cont; + int kind; + int len; + char *buf; + char c; + char *p; + int fd; + int cont; struct timeval timeoutval; - fd_set readmask; - int fds; + fd_set readmask; + int fds; cont = 1; @@ -60,7 +61,7 @@ void read_until_ready_for_query(PGconn *conn, int timeout) { fd = PQsocket(conn); - for(;;) + for (;;) { FD_ZERO(&readmask); FD_SET(fd, &readmask); @@ -92,37 +93,37 @@ void read_until_ready_for_query(PGconn *conn, int timeout) } kind = read_char(conn); - switch(kind) + switch (kind) { - case '1': /* Parse complete */ + case '1': /* Parse complete */ fprintf(stderr, "<= BE ParseComplete\n"); read_and_discard(conn); break; - case '2': /* Bind complete */ + case '2': /* Bind complete */ fprintf(stderr, "<= BE BindComplete\n"); read_and_discard(conn); break; - case '3': /* Close complete */ + case '3': /* Close complete */ fprintf(stderr, "<= BE CloseComplete\n"); read_and_discard(conn); break; - case 'C': /* Command complete */ + case 'C': /* Command complete */ len = read_int32(conn); buf = read_bytes(len - sizeof(int), conn); fprintf(stderr, "<= BE CommandComplete(%s)\n", buf); pg_free(buf); break; - case 'D': /* Data row */ + case 'D': /* Data row */ fprintf(stderr, "<= BE DataRow\n"); read_and_discard(conn); break; - case 'E': /* Error response */ - case 'N': /* Notice response */ + case 'E': /* Error response */ + case 'N': /* Notice response */ if (kind == 'E') fprintf(stderr, "<= BE ErrorResponse("); else @@ -134,7 +135,7 @@ void read_until_ready_for_query(PGconn *conn, int timeout) fprintf(stderr, "%c ", *p); p++; fprintf(stderr, "%s ", p); - p += strlen(p)+1; + p += strlen(p) + 1; } fprintf(stderr, ")\n"); @@ -142,69 +143,69 @@ void read_until_ready_for_query(PGconn *conn, int timeout) pg_free(buf); break; - case 'G': /* Copy in response */ + case 'G': /* Copy in response */ fprintf(stderr, "<= BE CopyInResponse\n"); read_and_discard(conn); break; - case 'H': /* Copy out response */ + case 'H': /* Copy out response */ fprintf(stderr, "<= BE CopyOutResponse\n"); read_and_discard(conn); break; - case 'I': /* Empty query response */ + case 'I': /* Empty query response */ fprintf(stderr, "<= BE EmptyQueryResponse\n"); read_and_discard(conn); break; - case 'S': /* Parameter status */ + case 'S': /* Parameter status */ fprintf(stderr, "<= BE ParameterStatus\n"); read_and_discard(conn); break; - case 'T': /* Row Description */ + case 'T': /* Row Description */ fprintf(stderr, "<= BE RowDescription\n"); read_and_discard(conn); break; - case 'V': /* Function call response */ + case 'V': /* Function call response */ fprintf(stderr, "<= BE FunctionCallResponse\n"); read_and_discard(conn); break; - case 'W': /* Copy both response */ + case 'W': /* Copy both response */ fprintf(stderr, "<= BE CopyBothResponse\n"); read_and_discard(conn); break; - case 'Z': /* Ready for Query */ + case 'Z': /* Ready for Query */ len = read_int32(conn); c = read_char(conn); fprintf(stderr, "<= BE ReadyForQuery(%c)\n", c); cont = 0; break; - case 'c': /* Copy Done */ + case 'c': /* Copy Done */ fprintf(stderr, "<= BE CopyDone\n"); read_and_discard(conn); break; - case 'd': /* Copy Data */ + case 'd': /* Copy Data */ fprintf(stderr, "<= BE CopyData\n"); read_and_discard(conn); break; - case 'n': /* No data */ + case 'n': /* No data */ fprintf(stderr, "<= BE NoData\n"); read_and_discard(conn); break; - case 's': /* Portal suspended */ + case 's': /* Portal suspended */ fprintf(stderr, "<= BE PortalSuspended\n"); read_and_discard(conn); break; - case 't': /* Parameter description */ + case 't': /* Parameter description */ fprintf(stderr, "<= BE ParameterDescription\n"); read_and_discard(conn); break; @@ -218,7 +219,7 @@ void read_until_ready_for_query(PGconn *conn, int timeout) /* If nap-bwteen-line is requested, nap for some time */ if (read_nap > 0) { - (void)usleep(read_nap); + (void) usleep(read_nap); } } } @@ -226,11 +227,12 @@ void read_until_ready_for_query(PGconn *conn, int timeout) /* * Read a character from connection. */ -static char read_char(PGconn *conn) +static char +read_char(PGconn *conn) { - char c; + char c; - read_it(conn, (char *)&c, sizeof(c)); + read_it(conn, (char *) &c, sizeof(c)); return c; } @@ -238,11 +240,12 @@ static char read_char(PGconn *conn) /* * Read an integer from connection. */ -static int read_int32(PGconn *conn) +static int +read_int32(PGconn *conn) { - int len; + int len; - read_it(conn, (char *)&len, sizeof(len)); + read_it(conn, (char *) &len, sizeof(len)); return ntohl(len); } @@ -250,11 +253,12 @@ static int read_int32(PGconn *conn) /* * Read a short integer from connection. */ -static int read_int16(PGconn *conn) +static int +read_int16(PGconn *conn) { - short len; + short len; - read_it(conn, (char *)&len, sizeof(len)); + read_it(conn, (char *) &len, sizeof(len)); return ntohs(len); } @@ -263,9 +267,10 @@ static int read_int16(PGconn *conn) * Read specified length of bytes from connection. * pg_malloc'ed buffer is returned. */ -static char *read_bytes(int len, PGconn *conn) +static char * +read_bytes(int len, PGconn *conn) { - char *buf; + char *buf; buf = pg_malloc(len); @@ -277,10 +282,11 @@ static char *read_bytes(int len, PGconn *conn) /* * Read and discard a packet. */ -static void read_and_discard(PGconn *conn) +static void +read_and_discard(PGconn *conn) { - int len; - char *buf; + int len; + char *buf; len = read_int32(conn); @@ -294,9 +300,10 @@ static void read_and_discard(PGconn *conn) /* * Read requested bytes from conn. exit in case of error or EOF. */ -static void read_it(PGconn *conn, char *buf, int len) +static void +read_it(PGconn *conn, char *buf, int len) { - int sts; + int sts; if (len <= 0) return; @@ -321,5 +328,5 @@ static void read_it(PGconn *conn, char *buf, int len) if (len <= 0) break; - } + } } diff --git a/src/tools/pgproto/send.c b/src/tools/pgproto/send.c index 5b29ba5ab..c31b224fe 100644 --- a/src/tools/pgproto/send.c +++ b/src/tools/pgproto/send.c @@ -31,9 +31,10 @@ /* * Send a character to the connection. */ -void send_char(char c, PGconn *conn) +void +send_char(char c, PGconn *conn) { - int status; + int status; status = write(PQsocket(conn), &c, 1); } @@ -41,10 +42,11 @@ void send_char(char c, PGconn *conn) /* * Send a 4-byte integer to the connection. */ -void send_int(int intval, PGconn *conn) +void +send_int(int intval, PGconn *conn) { - int status; - int l = htonl(intval); + int status; + int l = htonl(intval); status = write(PQsocket(conn), &l, sizeof(l)); } @@ -52,10 +54,11 @@ void send_int(int intval, PGconn *conn) /* * Send a 2-byte integer to the connection. */ -void send_int16(short shortval, PGconn *conn) +void +send_int16(short shortval, PGconn *conn) { - int status; - short s = htons(shortval); + int status; + short s = htons(shortval); status = write(PQsocket(conn), &s, sizeof(s)); } @@ -63,19 +66,21 @@ void send_int16(short shortval, PGconn *conn) /* * Send a string to the connection. buf must be NULL terminated. */ -void send_string(char *buf, PGconn *conn) +void +send_string(char *buf, PGconn *conn) { - int status; + int status; - status = write(PQsocket(conn), buf, strlen(buf)+1); + status = write(PQsocket(conn), buf, strlen(buf) + 1); } /* * Send byte to the connection. */ -void send_byte(char *buf, int len, PGconn *conn) +void +send_byte(char *buf, int len, PGconn *conn) { - int status; + int status; status = write(PQsocket(conn), buf, len); } diff --git a/src/utils/error/elog.c b/src/utils/error/elog.c index 114083612..74928e329 100644 --- a/src/utils/error/elog.c +++ b/src/utils/error/elog.c @@ -82,11 +82,11 @@ static struct ONEXIT { void (*function) (int code, Datum arg); Datum arg; -} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS]; +} on_proc_exit_list[MAX_ON_EXITS], on_shmem_exit_list[MAX_ON_EXITS]; static int on_proc_exit_index, on_shmem_exit_index; -struct ONEXIT on_exit_prepare = {NULL,0L}; +struct ONEXIT on_exit_prepare = {NULL, 0L}; /* * This flag tracks whether we've called atexit() in the current process @@ -165,7 +165,9 @@ static int errordata_stack_depth = -1; /* index of topmost active frame */ static int recursion_depth = 0; /* to detect actual recursion */ -static int frontend_error_recursion_depth = 0; /* to detect recursion in delivering error to frontend clients */ +static int frontend_error_recursion_depth = 0; /* to detect recursion in + * delivering error to + * frontend clients */ /* Macro for checking errordata_stack_depth is reasonable */ @@ -221,6 +223,7 @@ errstart(int elevel, const char *filename, int lineno, bool output_to_client = false; int i; int frontend_invalid = false; + /* * Check some cases in which we want to promote an error into a more * severe error. None of this logic applies for non-error messages. @@ -283,8 +286,8 @@ errstart(int elevel, const char *filename, int lineno, * reasons and because many clients can't handle NOTICE messages * during authentication. */ - output_to_client = (elevel >= pool_config->client_min_messages || - elevel == INFO || elevel == FRONTEND_ONLY_ERROR); + output_to_client = (elevel >= pool_config->client_min_messages || + elevel == INFO || elevel == FRONTEND_ONLY_ERROR); } /* Skip processing effort if non-error message will not be output */ @@ -323,7 +326,7 @@ errstart(int elevel, const char *filename, int lineno, * because it suggests an infinite loop of errors during error * recovery. */ - errordata_stack_depth = -1; /* make room on stack */ + errordata_stack_depth = -1; /* make room on stack */ ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded"))); } @@ -334,7 +337,9 @@ errstart(int elevel, const char *filename, int lineno, edata->frontend_invalid = frontend_invalid; edata->output_to_server = output_to_server; edata->output_to_client = output_to_client; - if(elevel == FATAL && PG_exception_stack == NULL) /* This is startup failure. Take down main process with it */ + if (elevel == FATAL && PG_exception_stack == NULL) /* This is startup + * failure. Take down + * main process with it */ edata->retcode = POOL_EXIT_FATAL; else edata->retcode = POOL_EXIT_AND_RESTART; @@ -353,7 +358,7 @@ errstart(int elevel, const char *filename, int lineno, /* the default text domain is the backend's */ edata->domain = domain ? domain : PG_TEXTDOMAIN("pgpool"); - edata->saved_errno = errno; + edata->saved_errno = errno; /* * Any allocations for this error state level should go into ErrorContext @@ -377,7 +382,7 @@ errfinish(int dummy,...) { ErrorData *edata = &errordata[errordata_stack_depth]; int elevel = edata->elevel; - int retcode = edata->retcode; + int retcode = edata->retcode; MemoryContext oldcontext; ErrorContextCallback *econtext; @@ -528,17 +533,18 @@ errcode_ign(int sqlerrcode) return 0; /* return value does not matter */ } -int pool_error_code(const char *errcode) +int +pool_error_code(const char *errcode) { - ErrorData *edata = &errordata[errordata_stack_depth]; + ErrorData *edata = &errordata[errordata_stack_depth]; MemoryContext oldcontext; - + recursion_depth++; CHECK_STACK_DEPTH(); oldcontext = MemoryContextSwitchTo(edata->assoc_context); - + edata->pgpool_errcode = pstrdup(errcode); - + MemoryContextSwitchTo(oldcontext); recursion_depth--; return 0; /* return value does not matter */ @@ -931,7 +937,8 @@ errposition(int cursorpos) return 0; /* return value does not matter */ } -int return_code(int retcode) +int +return_code(int retcode) { ErrorData *edata = &errordata[errordata_stack_depth]; @@ -940,10 +947,11 @@ int return_code(int retcode) edata->retcode = retcode; - return retcode; /* return value does not matter */ + return retcode; /* return value does not matter */ } -int get_return_code(void) +int +get_return_code(void) { ErrorData *edata = &errordata[errordata_stack_depth]; @@ -976,7 +984,8 @@ geterrcode(void) * This is only intended for use in error callback subroutines, since there * is no other place outside elog.c where the concept is meaningful. */ -bool getfrontendinvalid(void) +bool +getfrontendinvalid(void) { ErrorData *edata = &errordata[errordata_stack_depth]; @@ -985,6 +994,7 @@ bool getfrontendinvalid(void) return edata->frontend_invalid; } + /* * geterrposition --- return the currently set error position (0 if none) * @@ -1028,7 +1038,7 @@ elog_start(const char *filename, int lineno, const char *funcname) * else failure to convert it to client encoding could cause further * recursion. */ - errordata_stack_depth = -1; /* make room on stack */ + errordata_stack_depth = -1; /* make room on stack */ ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded"))); } @@ -1275,7 +1285,7 @@ ReThrowError(ErrorData *edata) * because it suggests an infinite loop of errors during error * recovery. */ - errordata_stack_depth = -1; /* make room on stack */ + errordata_stack_depth = -1; /* make room on stack */ ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded"))); } @@ -1338,8 +1348,8 @@ pg_re_throw(void) Assert(edata->elevel == ERROR); edata->elevel = FATAL; - edata->output_to_server = (FATAL >= pool_config->log_min_messages); - edata->output_to_client = (FATAL >= pool_config->client_min_messages); + edata->output_to_server = (FATAL >= pool_config->log_min_messages); + edata->output_to_client = (FATAL >= pool_config->client_min_messages); /* * We can use errfinish() for the rest, but we don't want it to call @@ -1353,7 +1363,8 @@ pg_re_throw(void) /* Doesn't return ... */ ExceptionalCondition("pg_re_throw tried to return", "FailedAssertion", - __FILE__, __LINE__);} + __FILE__, __LINE__); +} /* @@ -1370,8 +1381,8 @@ pg_re_throw(void) char * GetErrorContextStack(void) { - ErrorData *edata; - ErrorContextCallback *econtext; + ErrorData *edata; + ErrorContextCallback *econtext; /* * Okay, crank up a stack entry to store the info in. @@ -1385,7 +1396,7 @@ GetErrorContextStack(void) * because it suggests an infinite loop of errors during error * recovery. */ - errordata_stack_depth = -1; /* make room on stack */ + errordata_stack_depth = -1; /* make room on stack */ ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded"))); } @@ -1406,8 +1417,8 @@ GetErrorContextStack(void) * into edata->context. * * Errors occurring in callback functions should go through the regular - * error handling code which should handle any recursive errors, though - * we double-check above, just in case. + * error handling code which should handle any recursive errors, though we + * double-check above, just in case. */ for (econtext = error_context_stack; econtext != NULL; @@ -1531,12 +1542,10 @@ write_syslog(int level, const char *line) memcpy(buf, line, buflen); buf[buflen] = '\0'; - /* trim to multibyte letter boundary - buflen = pg_mbcliplen(buf, buflen, buflen); - if (buflen <= 0) - return; - buf[buflen] = '\0'; -*/ + /* + * trim to multibyte letter boundary buflen = pg_mbcliplen(buf, + * buflen, buflen); if (buflen <= 0) return; buf[buflen] = '\0'; + */ /* already word boundary? */ if (line[buflen] != '\0' && !isspace((unsigned char) line[buflen])) @@ -1566,7 +1575,7 @@ write_syslog(int level, const char *line) syslog(level, "[%lu] %s", seq, line); } } -#endif /* HAVE_VSYSLOG */ +#endif /* HAVE_VSYSLOG */ #ifdef WIN32 /* @@ -1669,7 +1678,7 @@ write_eventlog(int level, const char *line, int len) &line, NULL); } -#endif /* WIN32 */ +#endif /* WIN32 */ static void write_console(const char *line, int len) @@ -1746,20 +1755,23 @@ write_console(const char *line, int len) static void send_message_to_frontend(ErrorData *edata) { - int protoVersion = PROTO_MAJOR_V3; /* default protocol version is V3 also used by pcp lib */ + int protoVersion = PROTO_MAJOR_V3; /* default protocol version is + * V3 also used by pcp lib */ - if (pool_frontend_exists() < 0 ) + if (pool_frontend_exists() < 0) return; + /* * Leave if we are failing on sending the message to frontend. */ if (++frontend_error_recursion_depth > 2) return; - if(processType == PT_CHILD) + if (processType == PT_CHILD) { /* - * Do not forward the debug messages to client before session is initialized + * Do not forward the debug messages to client before session is + * initialized */ if (edata->elevel < ERROR && pool_get_session_context(true) == NULL) { @@ -1772,107 +1784,109 @@ send_message_to_frontend(ErrorData *edata) if (protoVersion == PROTO_MAJOR_V2) { - char* message = edata->message?edata->message:"missing error text"; - pool_send_to_frontend((edata->elevel < ERROR) ? "N" : "E", 1,false); - pool_send_to_frontend(message, strlen(message),false); - pool_send_to_frontend("\n", 1,true); + char *message = edata->message ? edata->message : "missing error text"; + + pool_send_to_frontend((edata->elevel < ERROR) ? "N" : "E", 1, false); + pool_send_to_frontend(message, strlen(message), false); + pool_send_to_frontend("\n", 1, true); } else if (protoVersion == PROTO_MAJOR_V3) { - /* - * Buffer length for each message part - */ + /* + * Buffer length for each message part + */ #define MAXMSGBUF 256 - /* - * Buffer length for result message buffer. - * Since msg is consisted of 7 parts, msg buffer should be large - * enough to hold those message parts - */ + /* + * Buffer length for result message buffer. Since msg is consisted of + * 7 parts, msg buffer should be large enough to hold those message + * parts + */ #define MAXDATA (MAXMSGBUF+1)*7+1 - char data[MAXDATA]; - char msgbuf[MAXMSGBUF+1]; - int len; - int thislen; - int sendlen; - + char data[MAXDATA]; + char msgbuf[MAXMSGBUF + 1]; + int len; + int thislen; + int sendlen; + len = 0; memset(data, 0, MAXDATA); pool_send_to_frontend((edata->elevel < ERROR) ? "N" : "E", 1, false); /* error level */ - thislen = snprintf(msgbuf, MAXMSGBUF, "S%s", error_severity(edata->elevel,true)); + thislen = snprintf(msgbuf, MAXMSGBUF, "S%s", error_severity(edata->elevel, true)); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; - + /* code */ - thislen = snprintf(msgbuf, MAXMSGBUF, "C%s", edata->pgpool_errcode?edata->pgpool_errcode:"XX000"); + thislen = snprintf(msgbuf, MAXMSGBUF, "C%s", edata->pgpool_errcode ? edata->pgpool_errcode : "XX000"); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; - + /* message */ - thislen = snprintf(msgbuf, MAXMSGBUF, "M%s", edata->message?edata->message:"missing error text"); + thislen = snprintf(msgbuf, MAXMSGBUF, "M%s", edata->message ? edata->message : "missing error text"); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; - + /* detail */ if (edata->detail) { thislen = snprintf(msgbuf, MAXMSGBUF, "D%s", edata->detail); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; } - + /* hint */ - if (edata->hint ) + if (edata->hint) { thislen = snprintf(msgbuf, MAXMSGBUF, "H%s", edata->hint); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; } - + /* file */ thislen = snprintf(msgbuf, MAXMSGBUF, "F%s", edata->filename); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; - + /* line */ thislen = snprintf(msgbuf, MAXMSGBUF, "L%d", edata->lineno); thislen = Min(thislen, MAXMSGBUF); - memcpy(data +len, msgbuf, thislen+1); + memcpy(data + len, msgbuf, thislen + 1); len += thislen + 1; - + /* stop null */ len++; *(data + len - 1) = '\0'; - + sendlen = len; len = htonl(len + 4); - pool_send_to_frontend((char*)&len, sizeof(len), false); + pool_send_to_frontend((char *) &len, sizeof(len), false); pool_send_to_frontend(data, sendlen, true); } if (edata->elevel == FRONTEND_ONLY_ERROR) { - /* send the ready for query to complete - * the frontend error cycle + /* + * send the ready for query to complete the frontend error cycle */ /* ready for query */ - pool_send_to_frontend((char*)"Z", 1, true); + pool_send_to_frontend((char *) "Z", 1, true); if (protoVersion == PROTO_MAJOR_V3) { - int len = htonl(5); - pool_send_to_frontend((char*)&len, sizeof(len), false); - pool_send_to_frontend((char*)"I", 1, true); + int len = htonl(5); + + pool_send_to_frontend((char *) &len, sizeof(len), false); + pool_send_to_frontend((char *) "I", 1, true); } } @@ -1894,24 +1908,24 @@ process_log_prefix_padding(const char *p, int *ppadding) { int paddingsign = 1; int padding = 0; - + if (*p == '-') { p++; - + if (*p == '\0') /* Did the buf end in %- ? */ return NULL; paddingsign = -1; } - + /* generate an int version of the numerical string */ while (*p >= '0' && *p <= '9') padding = padding * 10 + (*p++ - '0'); - + /* format is invalid if it ends with the padding number */ if (*p == '\0') return NULL; - + padding *= paddingsign; *ppadding = padding; return p; @@ -1934,7 +1948,8 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) POOL_CONNECTION *frontend = NULL; POOL_SESSION_CONTEXT *session = pool_get_session_context(true); - if(session) + + if (session) frontend = session->frontend; /* @@ -1949,7 +1964,7 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) log_my_pid = MyProcPid; } log_line_number++; - + if (line_prefix == NULL) return; /* in case guc hasn't run yet */ @@ -1961,7 +1976,7 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) appendStringInfoChar(buf, *p); continue; } - + /* must be a '%', so skip to the next char */ p++; if (*p == '\0') @@ -1991,29 +2006,30 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) padding = 0; else if ((p = process_log_prefix_padding(p, &padding)) == NULL) break; - + /* process the option */ switch (*p) { - case 'a': /* application name */ - { + case 'a': /* application name */ + { - /* - * Do not use MASTER_CONNECTION macro here since it calls - * pool_virtual_master_db_node_id() which eventually calls - * ereport() if operated in DEBUG mode. - */ - StartupPacket *sp = session? (session->backend->slots[REAL_MASTER_NODE_ID])->sp : NULL ; - const char *appname = sp? sp->application_name : "[No Connection]"; - if (appname == NULL || *appname == '\0') - appname = "[unknown]"; - if (padding != 0) - appendStringInfo(buf, "%*s", padding, appname); - else - appendStringInfoString(buf, appname); - } + /* + * Do not use MASTER_CONNECTION macro here since it calls + * pool_virtual_master_db_node_id() which eventually calls + * ereport() if operated in DEBUG mode. + */ + StartupPacket *sp = session ? (session->backend->slots[REAL_MASTER_NODE_ID])->sp : NULL; + const char *appname = sp ? sp->application_name : "[No Connection]"; + + if (appname == NULL || *appname == '\0') + appname = "[unknown]"; + if (padding != 0) + appendStringInfo(buf, "%*s", padding, appname); + else + appendStringInfoString(buf, appname); + } break; - case 'P': /* process name */ + case 'P': /* process name */ { if (padding != 0) appendStringInfo(buf, "%*s", padding, process_name()); @@ -2023,7 +2039,8 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) break; case 'u': { - const char *username = frontend? frontend->username : "[No Connection]"; + const char *username = frontend ? frontend->username : "[No Connection]"; + if (username == NULL || *username == '\0') username = "[unknown]"; @@ -2035,7 +2052,7 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) break; case 'd': { - const char *dbname = frontend? frontend->database : "[No Connection]"; + const char *dbname = frontend ? frontend->database : "[No Connection]"; if (dbname == NULL || *dbname == '\0') dbname = "[unknown]"; @@ -2059,16 +2076,17 @@ log_line_prefix(StringInfo buf, const char *line_prefix, ErrorData *edata) appendStringInfo(buf, "%ld", log_line_number); break; case 't': - { - char strbuf[129]; - time_t now = time(NULL); - strftime(strbuf, 128, "%Y-%m-%d %H:%M:%S", localtime(&now)); + { + char strbuf[129]; + time_t now = time(NULL); - if (padding != 0) - appendStringInfo(buf, "%*s", padding, strbuf); - else - appendStringInfoString(buf, strbuf); - } + strftime(strbuf, 128, "%Y-%m-%d %H:%M:%S", localtime(&now)); + + if (padding != 0) + appendStringInfo(buf, "%*s", padding, strbuf); + else + appendStringInfoString(buf, strbuf); + } break; default: /* format error - ignore it */ @@ -2088,7 +2106,7 @@ send_message_to_server_log(ErrorData *edata) initStringInfo(&buf); log_line_prefix(&buf, pool_config->log_line_prefix, edata); - appendStringInfo(&buf, "%s: ", error_severity(edata->elevel,false)); + appendStringInfo(&buf, "%s: ", error_severity(edata->elevel, false)); if (edata->message) @@ -2164,7 +2182,7 @@ send_message_to_server_log(ErrorData *edata) #ifdef HAVE_VSYSLOG /* Write to syslog, if enabled */ if (pool_config->log_destination & LOG_DESTINATION_SYSLOG) - { + { int syslog_level; switch (edata->elevel) @@ -2199,7 +2217,7 @@ send_message_to_server_log(ErrorData *edata) } write_syslog(syslog_level, buf.data); } -#endif /* HAVE_VSYSLOG */ +#endif /* HAVE_VSYSLOG */ if (pool_config->log_destination & LOG_DESTINATION_STDERR) { @@ -2550,15 +2568,16 @@ proc_exit_prepare(int code) * elog(FATAL) for example.) */ error_context_stack = NULL; - /* - * call on exit prepare if some function is specified - * this extention is added by pgpool - */ - if(on_exit_prepare.function) - { - (*on_exit_prepare.function) (code,on_exit_prepare.arg); - on_exit_prepare.function = NULL; - } + + /* + * call on exit prepare if some function is specified this extention is + * added by pgpool + */ + if (on_exit_prepare.function) + { + (*on_exit_prepare.function) (code, on_exit_prepare.arg); + on_exit_prepare.function = NULL; + } /* do our shared memory exits first */ shmem_exit(code); @@ -2576,7 +2595,7 @@ proc_exit_prepare(int code) */ while (--on_proc_exit_index >= 0) (*on_proc_exit_list[on_proc_exit_index].function) (code, - on_proc_exit_list[on_proc_exit_index].arg); + on_proc_exit_list[on_proc_exit_index].arg); on_proc_exit_index = 0; } @@ -2601,7 +2620,7 @@ shmem_exit(int code) */ while (--on_shmem_exit_index >= 0) (*on_shmem_exit_list[on_shmem_exit_index].function) (code, - on_shmem_exit_list[on_shmem_exit_index].arg); + on_shmem_exit_list[on_shmem_exit_index].arg); on_shmem_exit_index = 0; } @@ -2677,6 +2696,7 @@ on_shmem_exit(pg_on_exit_callback function, Datum arg) atexit_callback_setup = true; } } + /* ---------------------------------------------------------------- * on_system_exit * @@ -2684,10 +2704,11 @@ on_shmem_exit(pg_on_exit_callback function, Datum arg) * just before calling shmem_exit callbacks at process exit * ---------------------------------------------------------------- */ -void on_system_exit(pg_on_exit_callback function, Datum arg) +void +on_system_exit(pg_on_exit_callback function, Datum arg) { - on_exit_prepare.function = function; - on_exit_prepare.arg = arg; + on_exit_prepare.function = function; + on_exit_prepare.arg = arg; } /* ---------------------------------------------------------------- @@ -2722,6 +2743,6 @@ on_exit_reset(void) { on_shmem_exit_index = 0; on_proc_exit_index = 0; - on_exit_prepare.function = NULL; - on_exit_prepare.arg = (Datum)NULL; + on_exit_prepare.function = NULL; + on_exit_prepare.arg = (Datum) NULL; } diff --git a/src/utils/getopt_long.c b/src/utils/getopt_long.c index e8ba107d0..22597b715 100644 --- a/src/utils/getopt_long.c +++ b/src/utils/getopt_long.c @@ -52,7 +52,7 @@ int optreset; int getopt_long(int argc, char *const argv[], const char *optstring, - const struct option * longopts, int *longindex) + const struct option *longopts, int *longindex) { static char *place = EMSG; /* option letter processing */ char *oli; /* option letter list index */ @@ -113,7 +113,7 @@ getopt_long(int argc, char *const argv[], return BADARG; if (opterr) fprintf(stderr, - "%s: option requires an argument -- %s\n", + "%s: option requires an argument -- %s\n", argv[0], place); place = EMSG; optind++; diff --git a/src/utils/json.c b/src/utils/json.c index eee00c120..319c8fdbf 100644 --- a/src/utils/json.c +++ b/src/utils/json.c @@ -52,9 +52,9 @@ #include "utils/json.h" #ifdef _MSC_VER - #ifndef _CRT_SECURE_NO_WARNINGS - #define _CRT_SECURE_NO_WARNINGS - #endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif #endif const struct _json_value json_value_none; @@ -75,151 +75,171 @@ const struct _json_value json_value_none; typedef unsigned int json_uchar; -static unsigned char hex_value (json_char c) +static unsigned char +hex_value(json_char c) { - if (isdigit(c)) - return c - '0'; - - switch (c) { - case 'a': case 'A': return 0x0A; - case 'b': case 'B': return 0x0B; - case 'c': case 'C': return 0x0C; - case 'd': case 'D': return 0x0D; - case 'e': case 'E': return 0x0E; - case 'f': case 'F': return 0x0F; - default: return 0xFF; - } + if (isdigit(c)) + return c - '0'; + + switch (c) + { + case 'a': + case 'A': + return 0x0A; + case 'b': + case 'B': + return 0x0B; + case 'c': + case 'C': + return 0x0C; + case 'd': + case 'D': + return 0x0D; + case 'e': + case 'E': + return 0x0E; + case 'f': + case 'F': + return 0x0F; + default: + return 0xFF; + } } typedef struct { - unsigned long used_memory; + unsigned long used_memory; - unsigned int uint_max; - unsigned long ulong_max; + unsigned int uint_max; + unsigned long ulong_max; - json_settings settings; - int first_pass; + json_settings settings; + int first_pass; - const json_char * ptr; - unsigned int cur_line, cur_col; + const json_char *ptr; + unsigned int cur_line, + cur_col; -} json_state; +} json_state; -static void * default_alloc (size_t size, int zero, void * user_data) +static void * +default_alloc(size_t size, int zero, void *user_data) { - return zero ? palloc0 (size) : palloc (size); + return zero ? palloc0(size) : palloc(size); } -static void default_free (void * ptr, void * user_data) +static void +default_free(void *ptr, void *user_data) { - pfree (ptr); + pfree(ptr); } -static void * json_alloc (json_state * state, unsigned long size, int zero) +static void * +json_alloc(json_state * state, unsigned long size, int zero) { - if ((state->ulong_max - state->used_memory) < size) - return 0; + if ((state->ulong_max - state->used_memory) < size) + return 0; - if (state->settings.max_memory - && (state->used_memory += size) > state->settings.max_memory) - { - return 0; - } + if (state->settings.max_memory + && (state->used_memory += size) > state->settings.max_memory) + { + return 0; + } - return state->settings.mem_alloc (size, zero, state->settings.user_data); + return state->settings.mem_alloc(size, zero, state->settings.user_data); } -static int new_value (json_state * state, - json_value ** top, json_value ** root, json_value ** alloc, - json_type type) +static int +new_value(json_state * state, + json_value * *top, json_value * *root, json_value * *alloc, + json_type type) { - json_value * value; - int values_size; + json_value *value; + int values_size; - if (!state->first_pass) - { - value = *top = *alloc; - *alloc = (*alloc)->_reserved.next_alloc; + if (!state->first_pass) + { + value = *top = *alloc; + *alloc = (*alloc)->_reserved.next_alloc; - if (!*root) - *root = value; + if (!*root) + *root = value; - switch (value->type) - { - case json_array: + switch (value->type) + { + case json_array: - if (value->u.array.length == 0) - break; + if (value->u.array.length == 0) + break; - if (! (value->u.array.values = (json_value **) json_alloc - (state, value->u.array.length * sizeof (json_value *), 0)) ) - { - return 0; - } + if (!(value->u.array.values = (json_value * *) json_alloc + (state, value->u.array.length * sizeof(json_value *), 0))) + { + return 0; + } - value->u.array.length = 0; - break; + value->u.array.length = 0; + break; - case json_object: + case json_object: - if (value->u.object.length == 0) - break; + if (value->u.object.length == 0) + break; - values_size = sizeof (*value->u.object.values) * value->u.object.length; + values_size = sizeof(*value->u.object.values) * value->u.object.length; - if (! (value->u.object.values = (json_object_entry *) json_alloc - (state, values_size + ((unsigned long) value->u.object.values), 0)) ) - { - return 0; - } + if (!(value->u.object.values = (json_object_entry *) json_alloc + (state, values_size + ((unsigned long) value->u.object.values), 0))) + { + return 0; + } - value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; + value->_reserved.object_mem = (*(char **) &value->u.object.values) + values_size; - value->u.object.length = 0; - break; + value->u.object.length = 0; + break; - case json_string: + case json_string: - if (! (value->u.string.ptr = (json_char *) json_alloc - (state, (value->u.string.length + 1) * sizeof (json_char), 0)) ) - { - return 0; - } + if (!(value->u.string.ptr = (json_char *) json_alloc + (state, (value->u.string.length + 1) * sizeof(json_char), 0))) + { + return 0; + } - value->u.string.length = 0; - break; + value->u.string.length = 0; + break; - default: - break; - }; + default: + break; + }; - return 1; - } + return 1; + } - if (! (value = (json_value *) json_alloc - (state, sizeof (json_value) + state->settings.value_extra, 1))) - { - return 0; - } + if (!(value = (json_value *) json_alloc + (state, sizeof(json_value) + state->settings.value_extra, 1))) + { + return 0; + } - if (!*root) - *root = value; + if (!*root) + *root = value; - value->type = type; - value->parent = *top; + value->type = type; + value->parent = *top; - #ifdef JSON_TRACK_SOURCE - value->line = state->cur_line; - value->col = state->cur_col; - #endif +#ifdef JSON_TRACK_SOURCE + value->line = state->cur_line; + value->col = state->cur_col; +#endif - if (*alloc) - (*alloc)->_reserved.next_alloc = value; + if (*alloc) + (*alloc)->_reserved.next_alloc = value; - *alloc = *top = value; + *alloc = *top = value; - return 1; + return 1; } #define whitespace \ @@ -233,844 +253,875 @@ static int new_value (json_state * state, state.cur_line, state.cur_col static const long - flag_next = 1 << 0, - flag_reproc = 1 << 1, - flag_need_comma = 1 << 2, - flag_seek_value = 1 << 3, - flag_escaped = 1 << 4, - flag_string = 1 << 5, - flag_need_colon = 1 << 6, - flag_done = 1 << 7, - flag_num_negative = 1 << 8, - flag_num_zero = 1 << 9, - flag_num_e = 1 << 10, - flag_num_e_got_sign = 1 << 11, - flag_num_e_negative = 1 << 12, - flag_line_comment = 1 << 13, - flag_block_comment = 1 << 14; - -json_value * json_parse_ex (json_settings * settings, - const json_char * json, - size_t length, - char * error_buf) + flag_next = 1 << 0, + flag_reproc = 1 << 1, + flag_need_comma = 1 << 2, + flag_seek_value = 1 << 3, + flag_escaped = 1 << 4, + flag_string = 1 << 5, + flag_need_colon = 1 << 6, + flag_done = 1 << 7, + flag_num_negative = 1 << 8, + flag_num_zero = 1 << 9, + flag_num_e = 1 << 10, + flag_num_e_got_sign = 1 << 11, + flag_num_e_negative = 1 << 12, + flag_line_comment = 1 << 13, + flag_block_comment = 1 << 14; + +json_value * +json_parse_ex(json_settings * settings, + const json_char * json, + size_t length, + char *error_buf) { - json_char error [json_error_max]; - const json_char * end; - json_value * top, * root, * alloc = 0; - json_state state = { 0 }; - long flags; - long num_digits = 0, num_e = 0; - json_int_t num_fraction = 0; - - /* Skip UTF-8 BOM - */ - if (length >= 3 && ((unsigned char) json [0]) == 0xEF - && ((unsigned char) json [1]) == 0xBB - && ((unsigned char) json [2]) == 0xBF) - { - json += 3; - length -= 3; - } - - error[0] = '\0'; - end = (json + length); - - memcpy (&state.settings, settings, sizeof (json_settings)); - - if (!state.settings.mem_alloc) - state.settings.mem_alloc = default_alloc; - - if (!state.settings.mem_free) - state.settings.mem_free = default_free; - - memset (&state.uint_max, 0xFF, sizeof (state.uint_max)); - memset (&state.ulong_max, 0xFF, sizeof (state.ulong_max)); - - state.uint_max -= 8; /* limit of how much can be added before next check */ - state.ulong_max -= 8; - - for (state.first_pass = 1; state.first_pass >= 0; -- state.first_pass) - { - json_uchar uchar; - unsigned char uc_b1, uc_b2, uc_b3, uc_b4; - json_char * string = 0; - unsigned int string_length = 0; - - top = root = 0; - flags = flag_seek_value; - - state.cur_line = 1; - - for (state.ptr = json ;; ++ state.ptr) - { - json_char b = (state.ptr == end ? 0 : *state.ptr); - - if (flags & flag_string) - { - if (!b) - { - ereport(DEBUG1, - (errmsg("Unexpected EOF in JSON string (at %d:%d)", line_and_col))); - goto e_failed; - } - - if (string_length > state.uint_max) - goto e_overflow; - - if (flags & flag_escaped) - { - flags &= ~ flag_escaped; - - switch (b) - { - case 'b': string_add ('\b'); break; - case 'f': string_add ('\f'); break; - case 'n': string_add ('\n'); break; - case 'r': string_add ('\r'); break; - case 't': string_add ('\t'); break; - case 'u': - - if (end - state.ptr < 4 || - (uc_b1 = hex_value (*++ state.ptr)) == 0xFF || - (uc_b2 = hex_value (*++ state.ptr)) == 0xFF || - (uc_b3 = hex_value (*++ state.ptr)) == 0xFF || - (uc_b4 = hex_value (*++ state.ptr)) == 0xFF) - { - ereport(DEBUG1, - (errmsg("JSON ERROR, invalid character value `%c` (at %d:%d)", b, line_and_col))); - goto e_failed; - } - - uc_b1 = (uc_b1 << 4) | uc_b2; - uc_b2 = (uc_b3 << 4) | uc_b4; - uchar = (uc_b1 << 8) | uc_b2; - - if ((uchar & 0xF800) == 0xD800) { - json_uchar uchar2; - - if (end - state.ptr < 6 || (*++ state.ptr) != '\\' || (*++ state.ptr) != 'u' || - (uc_b1 = hex_value (*++ state.ptr)) == 0xFF || - (uc_b2 = hex_value (*++ state.ptr)) == 0xFF || - (uc_b3 = hex_value (*++ state.ptr)) == 0xFF || - (uc_b4 = hex_value (*++ state.ptr)) == 0xFF) - { - ereport(DEBUG1, - (errmsg("JSON ERROR, Invalid character value `%c` (at %d:%d)", b, line_and_col))); - goto e_failed; - } - - uc_b1 = (uc_b1 << 4) | uc_b2; - uc_b2 = (uc_b3 << 4) | uc_b4; - uchar2 = (uc_b1 << 8) | uc_b2; - - uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF); - } - - if (sizeof (json_char) >= sizeof (json_uchar) || (uchar <= 0x7F)) - { - string_add ((json_char) uchar); - break; - } - - if (uchar <= 0x7FF) - { - if (state.first_pass) - string_length += 2; - else - { string [string_length ++] = 0xC0 | (uchar >> 6); - string [string_length ++] = 0x80 | (uchar & 0x3F); - } - - break; - } - - if (uchar <= 0xFFFF) { - if (state.first_pass) - string_length += 3; - else - { string [string_length ++] = 0xE0 | (uchar >> 12); - string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F); - string [string_length ++] = 0x80 | (uchar & 0x3F); - } - - break; - } - - if (state.first_pass) - string_length += 4; - else - { string [string_length ++] = 0xF0 | (uchar >> 18); - string [string_length ++] = 0x80 | ((uchar >> 12) & 0x3F); - string [string_length ++] = 0x80 | ((uchar >> 6) & 0x3F); - string [string_length ++] = 0x80 | (uchar & 0x3F); - } - - break; - - default: - string_add (b); - }; - - continue; - } - - if (b == '\\') - { - flags |= flag_escaped; - continue; - } - - if (b == '"') - { - if (!state.first_pass) - string [string_length] = 0; - - flags &= ~ flag_string; - string = 0; - - switch (top->type) - { - case json_string: - - top->u.string.length = string_length; - flags |= flag_next; - - break; - - case json_object: - - if (state.first_pass) - (*(json_char **) &top->u.object.values) += string_length + 1; - else - { - top->u.object.values [top->u.object.length].name - = (json_char *) top->_reserved.object_mem; - - top->u.object.values [top->u.object.length].name_length - = string_length; - - (*(json_char **) &top->_reserved.object_mem) += string_length + 1; - } - - flags |= flag_seek_value | flag_need_colon; - continue; - - default: - break; - }; - } - else - { - string_add (b); - continue; - } - } - - if (state.settings.settings & json_enable_comments) - { - if (flags & (flag_line_comment | flag_block_comment)) - { - if (flags & flag_line_comment) - { - if (b == '\r' || b == '\n' || !b) - { - flags &= ~ flag_line_comment; - -- state.ptr; /* so null can be reproc'd */ - } - - continue; - } - - if (flags & flag_block_comment) - { - if (!b) - { - ereport(DEBUG1, - (errmsg("JSON ERROR, %d:%d: Unexpected EOF in block comment", line_and_col))); - - goto e_failed; - } - - if (b == '*' && state.ptr < (end - 1) && state.ptr [1] == '/') - { - flags &= ~ flag_block_comment; - ++ state.ptr; /* skip closing sequence */ - } - - continue; - } - } - else if (b == '/') - { - if (! (flags & (flag_seek_value | flag_done)) && top->type != json_object) - { - ereport(DEBUG1, - (errmsg("JSON ERROR, %d:%d: Comment not allowed here", line_and_col))); - - goto e_failed; - } - - if (++ state.ptr == end) - { - ereport(DEBUG1, - (errmsg("JSON ERROR, %d:%d: EOF unexpected", line_and_col))); - - goto e_failed; - } - - switch (b = *state.ptr) - { - case '/': - flags |= flag_line_comment; - continue; - - case '*': - flags |= flag_block_comment; - continue; - - default: - ereport(DEBUG1, - (errmsg("JSON ERROR, %d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b))); - goto e_failed; - }; - } - } - - if (flags & flag_done) - { - if (!b) - break; - - switch (b) - { - whitespace: - continue; - - default: - ereport(DEBUG1, - (errmsg("JSON ERROR, %d:%d: Trailing garbage: ", state.cur_line, state.cur_col))); - goto e_failed; - }; - } + json_char error[json_error_max]; + const json_char *end; + json_value *top, + *root, + *alloc = 0; + json_state state = {0}; + long flags; + long num_digits = 0, + num_e = 0; + json_int_t num_fraction = 0; + + /* + * Skip UTF-8 BOM + */ + if (length >= 3 && ((unsigned char) json[0]) == 0xEF + && ((unsigned char) json[1]) == 0xBB + && ((unsigned char) json[2]) == 0xBF) + { + json += 3; + length -= 3; + } - if (flags & flag_seek_value) - { - switch (b) - { - whitespace: - continue; + error[0] = '\0'; + end = (json + length); - case ']': + memcpy(&state.settings, settings, sizeof(json_settings)); - if (top && top->type == json_array) - flags = (flags & ~ (flag_need_comma | flag_seek_value)) | flag_next; - else - { - ereport(DEBUG1, - (errmsg("%d:%d: Unexpected ]", line_and_col))); + if (!state.settings.mem_alloc) + state.settings.mem_alloc = default_alloc; - goto e_failed; - } + if (!state.settings.mem_free) + state.settings.mem_free = default_free; - break; + memset(&state.uint_max, 0xFF, sizeof(state.uint_max)); + memset(&state.ulong_max, 0xFF, sizeof(state.ulong_max)); - default: + state.uint_max -= 8; /* limit of how much can be added before next + * check */ + state.ulong_max -= 8; - if (flags & flag_need_comma) - { - if (b == ',') - { flags &= ~ flag_need_comma; - continue; - } - else - { - ereport(DEBUG1, - (errmsg("%d:%d: Expected , before %c", - state.cur_line, state.cur_col, b))); + for (state.first_pass = 1; state.first_pass >= 0; --state.first_pass) + { + json_uchar uchar; + unsigned char uc_b1, + uc_b2, + uc_b3, + uc_b4; + json_char *string = 0; + unsigned int string_length = 0; - goto e_failed; - } - } + top = root = 0; + flags = flag_seek_value; - if (flags & flag_need_colon) - { - if (b == ':') - { flags &= ~ flag_need_colon; - continue; - } - else - { - ereport(DEBUG1, - (errmsg("%d:%d: Expected : before %c", - state.cur_line, state.cur_col, b))); + state.cur_line = 1; - goto e_failed; - } - } + for (state.ptr = json;; ++state.ptr) + { + json_char b = (state.ptr == end ? 0 : *state.ptr); - flags &= ~ flag_seek_value; + if (flags & flag_string) + { + if (!b) + { + ereport(DEBUG1, + (errmsg("Unexpected EOF in JSON string (at %d:%d)", line_and_col))); + goto e_failed; + } + + if (string_length > state.uint_max) + goto e_overflow; + + if (flags & flag_escaped) + { + flags &= ~flag_escaped; + + switch (b) + { + case 'b': + string_add('\b'); + break; + case 'f': + string_add('\f'); + break; + case 'n': + string_add('\n'); + break; + case 'r': + string_add('\r'); + break; + case 't': + string_add('\t'); + break; + case 'u': + + if (end - state.ptr < 4 || + (uc_b1 = hex_value(*++state.ptr)) == 0xFF || + (uc_b2 = hex_value(*++state.ptr)) == 0xFF || + (uc_b3 = hex_value(*++state.ptr)) == 0xFF || + (uc_b4 = hex_value(*++state.ptr)) == 0xFF) + { + ereport(DEBUG1, + (errmsg("JSON ERROR, invalid character value `%c` (at %d:%d)", b, line_and_col))); + goto e_failed; + } + + uc_b1 = (uc_b1 << 4) | uc_b2; + uc_b2 = (uc_b3 << 4) | uc_b4; + uchar = (uc_b1 << 8) | uc_b2; + + if ((uchar & 0xF800) == 0xD800) + { + json_uchar uchar2; + + if (end - state.ptr < 6 || (*++state.ptr) != '\\' || (*++state.ptr) != 'u' || + (uc_b1 = hex_value(*++state.ptr)) == 0xFF || + (uc_b2 = hex_value(*++state.ptr)) == 0xFF || + (uc_b3 = hex_value(*++state.ptr)) == 0xFF || + (uc_b4 = hex_value(*++state.ptr)) == 0xFF) + { + ereport(DEBUG1, + (errmsg("JSON ERROR, Invalid character value `%c` (at %d:%d)", b, line_and_col))); + goto e_failed; + } + + uc_b1 = (uc_b1 << 4) | uc_b2; + uc_b2 = (uc_b3 << 4) | uc_b4; + uchar2 = (uc_b1 << 8) | uc_b2; + + uchar = 0x010000 | ((uchar & 0x3FF) << 10) | (uchar2 & 0x3FF); + } + + if (sizeof(json_char) >= sizeof(json_uchar) || (uchar <= 0x7F)) + { + string_add((json_char) uchar); + break; + } + + if (uchar <= 0x7FF) + { + if (state.first_pass) + string_length += 2; + else + { + string[string_length++] = 0xC0 | (uchar >> 6); + string[string_length++] = 0x80 | (uchar & 0x3F); + } + + break; + } + + if (uchar <= 0xFFFF) + { + if (state.first_pass) + string_length += 3; + else + { + string[string_length++] = 0xE0 | (uchar >> 12); + string[string_length++] = 0x80 | ((uchar >> 6) & 0x3F); + string[string_length++] = 0x80 | (uchar & 0x3F); + } + + break; + } + + if (state.first_pass) + string_length += 4; + else + { + string[string_length++] = 0xF0 | (uchar >> 18); + string[string_length++] = 0x80 | ((uchar >> 12) & 0x3F); + string[string_length++] = 0x80 | ((uchar >> 6) & 0x3F); + string[string_length++] = 0x80 | (uchar & 0x3F); + } + + break; + + default: + string_add(b); + }; + + continue; + } + + if (b == '\\') + { + flags |= flag_escaped; + continue; + } + + if (b == '"') + { + if (!state.first_pass) + string[string_length] = 0; + + flags &= ~flag_string; + string = 0; + + switch (top->type) + { + case json_string: + + top->u.string.length = string_length; + flags |= flag_next; + + break; + + case json_object: + + if (state.first_pass) + (*(json_char * *) & top->u.object.values) += string_length + 1; + else + { + top->u.object.values[top->u.object.length].name + = (json_char *) top->_reserved.object_mem; + + top->u.object.values[top->u.object.length].name_length + = string_length; + + (*(json_char * *) & top->_reserved.object_mem) += string_length + 1; + } + + flags |= flag_seek_value | flag_need_colon; + continue; + + default: + break; + }; + } + else + { + string_add(b); + continue; + } + } + + if (state.settings.settings & json_enable_comments) + { + if (flags & (flag_line_comment | flag_block_comment)) + { + if (flags & flag_line_comment) + { + if (b == '\r' || b == '\n' || !b) + { + flags &= ~flag_line_comment; + --state.ptr; /* so null can be reproc'd */ + } + + continue; + } + + if (flags & flag_block_comment) + { + if (!b) + { + ereport(DEBUG1, + (errmsg("JSON ERROR, %d:%d: Unexpected EOF in block comment", line_and_col))); + + goto e_failed; + } + + if (b == '*' && state.ptr < (end - 1) && state.ptr[1] == '/') + { + flags &= ~flag_block_comment; + ++state.ptr; /* skip closing sequence */ + } + + continue; + } + } + else if (b == '/') + { + if (!(flags & (flag_seek_value | flag_done)) && top->type != json_object) + { + ereport(DEBUG1, + (errmsg("JSON ERROR, %d:%d: Comment not allowed here", line_and_col))); - switch (b) - { - case '{': + goto e_failed; + } - if (!new_value (&state, &top, &root, &alloc, json_object)) - goto e_alloc_failure; + if (++state.ptr == end) + { + ereport(DEBUG1, + (errmsg("JSON ERROR, %d:%d: EOF unexpected", line_and_col))); - continue; + goto e_failed; + } - case '[': + switch (b = *state.ptr) + { + case '/': + flags |= flag_line_comment; + continue; - if (!new_value (&state, &top, &root, &alloc, json_array)) - goto e_alloc_failure; + case '*': + flags |= flag_block_comment; + continue; - flags |= flag_seek_value; - continue; + default: + ereport(DEBUG1, + (errmsg("JSON ERROR, %d:%d: Unexpected `%c` in comment opening sequence", line_and_col, b))); + goto e_failed; + }; + } + } + + if (flags & flag_done) + { + if (!b) + break; + + switch (b) + { + whitespace: + continue; + + default: + ereport(DEBUG1, + (errmsg("JSON ERROR, %d:%d: Trailing garbage: ", state.cur_line, state.cur_col))); + goto e_failed; + }; + } + + if (flags & flag_seek_value) + { + switch (b) + { + whitespace: + continue; + + case ']': + + if (top && top->type == json_array) + flags = (flags & ~(flag_need_comma | flag_seek_value)) | flag_next; + else + { + ereport(DEBUG1, + (errmsg("%d:%d: Unexpected ]", line_and_col))); - case '"': - - if (!new_value (&state, &top, &root, &alloc, json_string)) - goto e_alloc_failure; - - flags |= flag_string; - - string = top->u.string.ptr; - string_length = 0; - - continue; - - case 't': - - if ((end - state.ptr) < 3 || *(++ state.ptr) != 'r' || - *(++ state.ptr) != 'u' || *(++ state.ptr) != 'e') - { - goto e_unknown_value; - } - - if (!new_value (&state, &top, &root, &alloc, json_boolean)) - goto e_alloc_failure; + goto e_failed; + } - top->u.boolean = 1; + break; - flags |= flag_next; - break; + default: - case 'f': + if (flags & flag_need_comma) + { + if (b == ',') + { + flags &= ~flag_need_comma; + continue; + } + else + { + ereport(DEBUG1, + (errmsg("%d:%d: Expected , before %c", + state.cur_line, state.cur_col, b))); - if ((end - state.ptr) < 4 || *(++ state.ptr) != 'a' || - *(++ state.ptr) != 'l' || *(++ state.ptr) != 's' || - *(++ state.ptr) != 'e') - { - goto e_unknown_value; - } + goto e_failed; + } + } - if (!new_value (&state, &top, &root, &alloc, json_boolean)) - goto e_alloc_failure; + if (flags & flag_need_colon) + { + if (b == ':') + { + flags &= ~flag_need_colon; + continue; + } + else + { + ereport(DEBUG1, + (errmsg("%d:%d: Expected : before %c", + state.cur_line, state.cur_col, b))); - flags |= flag_next; - break; + goto e_failed; + } + } - case 'n': + flags &= ~flag_seek_value; - if ((end - state.ptr) < 3 || *(++ state.ptr) != 'u' || - *(++ state.ptr) != 'l' || *(++ state.ptr) != 'l') - { - goto e_unknown_value; - } + switch (b) + { + case '{': - if (!new_value (&state, &top, &root, &alloc, json_null)) - goto e_alloc_failure; + if (!new_value(&state, &top, &root, &alloc, json_object)) + goto e_alloc_failure; - flags |= flag_next; - break; + continue; - default: + case '[': - if (isdigit (b) || b == '-') - { - if (!new_value (&state, &top, &root, &alloc, json_integer)) - goto e_alloc_failure; + if (!new_value(&state, &top, &root, &alloc, json_array)) + goto e_alloc_failure; - if (!state.first_pass) - { - while (isdigit (b) || b == '+' || b == '-' - || b == 'e' || b == 'E' || b == '.') - { - if ( (++ state.ptr) == end) - { - b = 0; - break; - } + flags |= flag_seek_value; + continue; - b = *state.ptr; - } + case '"': - flags |= flag_next | flag_reproc; - break; - } + if (!new_value(&state, &top, &root, &alloc, json_string)) + goto e_alloc_failure; - flags &= ~ (flag_num_negative | flag_num_e | - flag_num_e_got_sign | flag_num_e_negative | - flag_num_zero); + flags |= flag_string; - num_digits = 0; - num_fraction = 0; - num_e = 0; + string = top->u.string.ptr; + string_length = 0; + + continue; + + case 't': + + if ((end - state.ptr) < 3 || *(++state.ptr) != 'r' || + *(++state.ptr) != 'u' || *(++state.ptr) != 'e') + { + goto e_unknown_value; + } + + if (!new_value(&state, &top, &root, &alloc, json_boolean)) + goto e_alloc_failure; + + top->u.boolean = 1; + + flags |= flag_next; + break; + + case 'f': + + if ((end - state.ptr) < 4 || *(++state.ptr) != 'a' || + *(++state.ptr) != 'l' || *(++state.ptr) != 's' || + *(++state.ptr) != 'e') + { + goto e_unknown_value; + } - if (b != '-') - { - flags |= flag_reproc; - break; - } + if (!new_value(&state, &top, &root, &alloc, json_boolean)) + goto e_alloc_failure; - flags |= flag_num_negative; - continue; - } - else - { - ereport(DEBUG1, - (errmsg("%d:%d: Unexpected %c when seeking value", line_and_col, b))); - - goto e_failed; - } - }; - }; - } - else - { - switch (top->type) - { - case json_object: - - switch (b) - { - whitespace: - continue; - - case '"': - - if (flags & flag_need_comma) - { - ereport(DEBUG1, - (errmsg("JSON ERROR: %d:%d: Expected , before \"", line_and_col))); - goto e_failed; - } - - flags |= flag_string; - - string = (json_char *) top->_reserved.object_mem; - string_length = 0; - - break; - - case '}': - - flags = (flags & ~ flag_need_comma) | flag_next; - break; - - case ',': - - if (flags & flag_need_comma) - { - flags &= ~ flag_need_comma; - break; - } - - default: - ereport(DEBUG1, - (errmsg("JSON ERROR: %d:%d: Unexpected `%c` in object", line_and_col, b))); - goto e_failed; - }; - - break; - - case json_integer: - case json_double: - - if (isdigit (b)) - { - ++ num_digits; - - if (top->type == json_integer || flags & flag_num_e) - { - if (! (flags & flag_num_e)) - { - if (flags & flag_num_zero) - { - ereport(DEBUG1, - (errmsg("JSON ERROR: %d:%d: Unexpected `0` before `%c`", line_and_col, b))); - goto e_failed; - } - - if (num_digits == 1 && b == '0') - flags |= flag_num_zero; - } - else - { - flags |= flag_num_e_got_sign; - num_e = (num_e * 10) + (b - '0'); - continue; - } - - top->u.integer = (top->u.integer * 10) + (b - '0'); - continue; - } - - num_fraction = (num_fraction * 10) + (b - '0'); - continue; - } - - if (b == '+' || b == '-') - { - if ( (flags & flag_num_e) && !(flags & flag_num_e_got_sign)) - { - flags |= flag_num_e_got_sign; - - if (b == '-') - flags |= flag_num_e_negative; - - continue; - } - } - else if (b == '.' && top->type == json_integer) - { - if (!num_digits) - { - ereport(DEBUG1, - (errmsg("JSON ERROR: %d:%d: Expected digit before `.`", line_and_col))); - goto e_failed; - } - - top->type = json_double; - top->u.dbl = (double) top->u.integer; - - num_digits = 0; - continue; - } - - if (! (flags & flag_num_e)) - { - if (top->type == json_double) - { - if (!num_digits) - { - ereport(DEBUG1, - (errmsg("JSON ERROR: %d:%d: Expected digit after `.`", line_and_col))); - goto e_failed; - } - - top->u.dbl += ((double) num_fraction) / (pow (10.0, (double) num_digits)); - } - - if (b == 'e' || b == 'E') - { - flags |= flag_num_e; - - if (top->type == json_integer) - { - top->type = json_double; - top->u.dbl = (double) top->u.integer; - } - - num_digits = 0; - flags &= ~ flag_num_zero; - - continue; - } - } - else - { - if (!num_digits) - { - ereport(DEBUG1, - (errmsg("JSON ERROR: %d:%d: Expected digit after `e`", line_and_col))); - goto e_failed; - } - - top->u.dbl *= pow (10.0, (double) - (flags & flag_num_e_negative ? - num_e : num_e)); - } - - if (flags & flag_num_negative) - { - if (top->type == json_integer) - top->u.integer = - top->u.integer; - else - top->u.dbl = - top->u.dbl; - } - - flags |= flag_next | flag_reproc; - break; - - default: - break; - }; - } - - if (flags & flag_reproc) - { - flags &= ~ flag_reproc; - -- state.ptr; - } - - if (flags & flag_next) - { - flags = (flags & ~ flag_next) | flag_need_comma; - - if (!top->parent) - { - /* root value done */ - - flags |= flag_done; - continue; - } - - if (top->parent->type == json_array) - flags |= flag_seek_value; - - if (!state.first_pass) - { - json_value * parent = top->parent; - - switch (parent->type) - { - case json_object: - - parent->u.object.values - [parent->u.object.length].value = top; - - break; - - case json_array: - - parent->u.array.values - [parent->u.array.length] = top; - - break; - - default: - break; - }; - } - - if ( (++ top->parent->u.array.length) > state.uint_max) - goto e_overflow; - - top = top->parent; + flags |= flag_next; + break; - continue; - } - } + case 'n': - alloc = root; - } + if ((end - state.ptr) < 3 || *(++state.ptr) != 'u' || + *(++state.ptr) != 'l' || *(++state.ptr) != 'l') + { + goto e_unknown_value; + } + + if (!new_value(&state, &top, &root, &alloc, json_null)) + goto e_alloc_failure; + + flags |= flag_next; + break; - return root; + default: + + if (isdigit(b) || b == '-') + { + if (!new_value(&state, &top, &root, &alloc, json_integer)) + goto e_alloc_failure; + + if (!state.first_pass) + { + while (isdigit(b) || b == '+' || b == '-' + || b == 'e' || b == 'E' || b == '.') + { + if ((++state.ptr) == end) + { + b = 0; + break; + } + + b = *state.ptr; + } + + flags |= flag_next | flag_reproc; + break; + } + + flags &= ~(flag_num_negative | flag_num_e | + flag_num_e_got_sign | flag_num_e_negative | + flag_num_zero); + + num_digits = 0; + num_fraction = 0; + num_e = 0; + + if (b != '-') + { + flags |= flag_reproc; + break; + } + + flags |= flag_num_negative; + continue; + } + else + { + ereport(DEBUG1, + (errmsg("%d:%d: Unexpected %c when seeking value", line_and_col, b))); + + goto e_failed; + } + }; + }; + } + else + { + switch (top->type) + { + case json_object: + + switch (b) + { + whitespace: + continue; + + case '"': + + if (flags & flag_need_comma) + { + ereport(DEBUG1, + (errmsg("JSON ERROR: %d:%d: Expected , before \"", line_and_col))); + goto e_failed; + } + + flags |= flag_string; + + string = (json_char *) top->_reserved.object_mem; + string_length = 0; + + break; + + case '}': + + flags = (flags & ~flag_need_comma) | flag_next; + break; + + case ',': + + if (flags & flag_need_comma) + { + flags &= ~flag_need_comma; + break; + } + + default: + ereport(DEBUG1, + (errmsg("JSON ERROR: %d:%d: Unexpected `%c` in object", line_and_col, b))); + goto e_failed; + }; + + break; + + case json_integer: + case json_double: + + if (isdigit(b)) + { + ++num_digits; + + if (top->type == json_integer || flags & flag_num_e) + { + if (!(flags & flag_num_e)) + { + if (flags & flag_num_zero) + { + ereport(DEBUG1, + (errmsg("JSON ERROR: %d:%d: Unexpected `0` before `%c`", line_and_col, b))); + goto e_failed; + } + + if (num_digits == 1 && b == '0') + flags |= flag_num_zero; + } + else + { + flags |= flag_num_e_got_sign; + num_e = (num_e * 10) + (b - '0'); + continue; + } + + top->u.integer = (top->u.integer * 10) + (b - '0'); + continue; + } + + num_fraction = (num_fraction * 10) + (b - '0'); + continue; + } + + if (b == '+' || b == '-') + { + if ((flags & flag_num_e) && !(flags & flag_num_e_got_sign)) + { + flags |= flag_num_e_got_sign; + + if (b == '-') + flags |= flag_num_e_negative; + + continue; + } + } + else if (b == '.' && top->type == json_integer) + { + if (!num_digits) + { + ereport(DEBUG1, + (errmsg("JSON ERROR: %d:%d: Expected digit before `.`", line_and_col))); + goto e_failed; + } + + top->type = json_double; + top->u.dbl = (double) top->u.integer; + + num_digits = 0; + continue; + } + + if (!(flags & flag_num_e)) + { + if (top->type == json_double) + { + if (!num_digits) + { + ereport(DEBUG1, + (errmsg("JSON ERROR: %d:%d: Expected digit after `.`", line_and_col))); + goto e_failed; + } + + top->u.dbl += ((double) num_fraction) / (pow(10.0, (double) num_digits)); + } + + if (b == 'e' || b == 'E') + { + flags |= flag_num_e; + + if (top->type == json_integer) + { + top->type = json_double; + top->u.dbl = (double) top->u.integer; + } + + num_digits = 0; + flags &= ~flag_num_zero; + + continue; + } + } + else + { + if (!num_digits) + { + ereport(DEBUG1, + (errmsg("JSON ERROR: %d:%d: Expected digit after `e`", line_and_col))); + goto e_failed; + } + + top->u.dbl *= pow(10.0, (double) + (flags & flag_num_e_negative ? -num_e : num_e)); + } + + if (flags & flag_num_negative) + { + if (top->type == json_integer) + top->u.integer = -top->u.integer; + else + top->u.dbl = -top->u.dbl; + } + + flags |= flag_next | flag_reproc; + break; + + default: + break; + }; + } + + if (flags & flag_reproc) + { + flags &= ~flag_reproc; + --state.ptr; + } + + if (flags & flag_next) + { + flags = (flags & ~flag_next) | flag_need_comma; + + if (!top->parent) + { + /* root value done */ + + flags |= flag_done; + continue; + } + + if (top->parent->type == json_array) + flags |= flag_seek_value; + + if (!state.first_pass) + { + json_value *parent = top->parent; + + switch (parent->type) + { + case json_object: + + parent->u.object.values + [parent->u.object.length].value = top; + + break; + + case json_array: + + parent->u.array.values + [parent->u.array.length] = top; + + break; + + default: + break; + }; + } + + if ((++top->parent->u.array.length) > state.uint_max) + goto e_overflow; + + top = top->parent; + + continue; + } + } + + alloc = root; + } + + return root; e_unknown_value: ereport(DEBUG1, (errmsg("JSON ERROR: %d:%d: Unknown value", line_and_col))); - goto e_failed; + goto e_failed; e_alloc_failure: - strcpy (error, "Memory allocation failure"); - goto e_failed; + strcpy(error, "Memory allocation failure"); + goto e_failed; e_overflow: ereport(DEBUG1, (errmsg("JSON ERROR: %d:%d: Too long (caught overflow)", line_and_col))); - goto e_failed; + goto e_failed; e_failed: - if (error_buf) - { - if (*error) - strcpy (error_buf, error); - else - strcpy (error_buf, "Unknown error"); - } + if (error_buf) + { + if (*error) + strcpy(error_buf, error); + else + strcpy(error_buf, "Unknown error"); + } - if (state.first_pass) - alloc = root; + if (state.first_pass) + alloc = root; - while (alloc) - { - top = alloc->_reserved.next_alloc; - state.settings.mem_free (alloc, state.settings.user_data); - alloc = top; - } + while (alloc) + { + top = alloc->_reserved.next_alloc; + state.settings.mem_free(alloc, state.settings.user_data); + alloc = top; + } - if (!state.first_pass) - json_value_free_ex (&state.settings, root); + if (!state.first_pass) + json_value_free_ex(&state.settings, root); - return 0; + return 0; } -json_value * json_parse (const json_char * json, size_t length) +json_value * +json_parse(const json_char * json, size_t length) { - json_settings settings = { 0 }; - return json_parse_ex (&settings, json, length, 0); + json_settings settings = {0}; + + return json_parse_ex(&settings, json, length, 0); } -void json_value_free_ex (json_settings * settings, json_value * value) +void +json_value_free_ex(json_settings * settings, json_value * value) { - json_value * cur_value; + json_value *cur_value; - if (!value) - return; + if (!value) + return; - value->parent = 0; + value->parent = 0; - while (value) - { - switch (value->type) - { - case json_array: + while (value) + { + switch (value->type) + { + case json_array: - if (!value->u.array.length) - { - settings->mem_free (value->u.array.values, settings->user_data); - break; - } + if (!value->u.array.length) + { + settings->mem_free(value->u.array.values, settings->user_data); + break; + } - value = value->u.array.values [-- value->u.array.length]; - continue; + value = value->u.array.values[--value->u.array.length]; + continue; - case json_object: + case json_object: - if (!value->u.object.length) - { - settings->mem_free (value->u.object.values, settings->user_data); - break; - } + if (!value->u.object.length) + { + settings->mem_free(value->u.object.values, settings->user_data); + break; + } - value = value->u.object.values [-- value->u.object.length].value; - continue; + value = value->u.object.values[--value->u.object.length].value; + continue; - case json_string: + case json_string: - settings->mem_free (value->u.string.ptr, settings->user_data); - break; + settings->mem_free(value->u.string.ptr, settings->user_data); + break; - default: - break; - }; + default: + break; + }; - cur_value = value; - value = value->parent; - settings->mem_free (cur_value, settings->user_data); - } + cur_value = value; + value = value->parent; + settings->mem_free(cur_value, settings->user_data); + } } -void json_value_free (json_value * value) +void +json_value_free(json_value * value) { - json_settings settings = { 0 }; - settings.mem_free = default_free; - json_value_free_ex (&settings, value); + json_settings settings = {0}; + + settings.mem_free = default_free; + json_value_free_ex(&settings, value); } /********* pgpool extension:********/ @@ -1079,11 +1130,13 @@ void json_value_free (json_value * value) * pgpool extension: * search node with key from json object */ -json_value* json_get_value_for_key(json_value* source, const char* key) +json_value * +json_get_value_for_key(json_value * source, const char *key) { if (source->type == json_object) { - int x; + int x; + for (x = 0; x < source->u.object.length; x++) { if (strcasecmp(source->u.object.values[x].name, key) == 0) @@ -1092,7 +1145,7 @@ json_value* json_get_value_for_key(json_value* source, const char* key) } else ereport(DEBUG1, - (errmsg("JSON ERROR, Passed in json is not object node"))); + (errmsg("JSON ERROR, Passed in json is not object node"))); return NULL; } @@ -1103,17 +1156,18 @@ json_value* json_get_value_for_key(json_value* source, const char* key) * function returns -1 */ -int json_get_bool_value_for_key(json_value* source, const char* key, bool* value) +int +json_get_bool_value_for_key(json_value * source, const char *key, bool *value) { - json_value* jNode; + json_value *jNode; - jNode = json_get_value_for_key(source,key); + 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; + *value = jNode->u.integer ? true : false; } else return -1; @@ -1122,11 +1176,12 @@ int json_get_bool_value_for_key(json_value* source, const char* key, bool* value } -int json_get_int_value_for_key(json_value* source, const char* key, int* value) +int +json_get_int_value_for_key(json_value * source, const char *key, int *value) { - json_value* jNode; - - jNode = json_get_value_for_key(source,key); + json_value *jNode; + + jNode = json_get_value_for_key(source, key); if (jNode == NULL) return -1; if (jNode->type != json_integer) @@ -1135,15 +1190,16 @@ int json_get_int_value_for_key(json_value* source, const char* key, int* value) return 0; } -int json_get_long_value_for_key(json_value* source, const char* key, long* value) +int +json_get_long_value_for_key(json_value * source, const char *key, long *value) { - json_value* jNode; + json_value *jNode; - jNode = json_get_value_for_key(source,key); + jNode = json_get_value_for_key(source, key); if (jNode == NULL) - return -1; + return -1; if (jNode->type != json_integer) - return -1; + return -1; *value = jNode->u.integer; return 0; } @@ -1155,11 +1211,12 @@ int json_get_long_value_for_key(json_value* source, const char* key, long* value * function returns NULL */ -char* json_get_string_value_for_key(json_value* source, const char* key) +char * +json_get_string_value_for_key(json_value * source, const char *key) { - json_value* jNode; - - jNode = json_get_value_for_key(source,key); + json_value *jNode; + + jNode = json_get_value_for_key(source, key); if (jNode == NULL) return NULL; if (jNode->type != json_string) diff --git a/src/utils/json_writer.c b/src/utils/json_writer.c index f8d08fb43..1f7133843 100644 --- a/src/utils/json_writer.c +++ b/src/utils/json_writer.c @@ -26,14 +26,16 @@ #include "utils/palloc.h" #include "utils/json_writer.h" -static inline int jw_get_current_element_count(JsonNode* jNode); -static inline void jw_inc_current_element_count(JsonNode* jNode); -static inline JWElementType jw_get_current_element_type(JsonNode* jNode); +static inline int jw_get_current_element_count(JsonNode * jNode); +static inline void jw_inc_current_element_count(JsonNode * jNode); +static inline JWElementType jw_get_current_element_type(JsonNode * jNode); -JsonNode* jw_create(JWElementType rootElement, bool pretty_output) +JsonNode * +jw_create(JWElementType rootElement, bool pretty_output) { - JsonNode* jNode = palloc(sizeof(JsonNode)); + JsonNode *jNode = palloc(sizeof(JsonNode)); + jNode->buf = makeStringInfo(); jNode->stack_ptr = 0; jNode->pretty = pretty_output; @@ -41,17 +43,20 @@ JsonNode* jw_create(JWElementType rootElement, bool pretty_output) return jNode; } -JsonNode* jw_create_with_array(bool pretty_output) +JsonNode * +jw_create_with_array(bool pretty_output) { return jw_create(JWARRAY, pretty_output); } -JsonNode* jw_create_with_object(bool pretty_output) +JsonNode * +jw_create_with_object(bool pretty_output) { return jw_create(JWOBJECT, pretty_output); } -bool jw_put_string(JsonNode* jNode, char* key, char* value) +bool +jw_put_string(JsonNode * jNode, char *key, char *value) { if (key == NULL || value == NULL) return false; @@ -61,19 +66,21 @@ bool jw_put_string(JsonNode* jNode, char* key, char* value) return false; if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "\"%s\":\"%s\"",key,value); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "\"%s\":\"%s\"", key, value); jw_inc_current_element_count(jNode); return true; } /* for compatibility reasons we pack bool in int*/ -bool jw_put_bool(JsonNode* jNode, char* key, bool value) +bool +jw_put_bool(JsonNode * jNode, char *key, bool value) { - return jw_put_int(jNode,key,value?1:0); + return jw_put_int(jNode, key, value ? 1 : 0); } -bool jw_put_int(JsonNode* jNode, char* key, int value) +bool +jw_put_int(JsonNode * jNode, char *key, int value) { if (key == NULL) return false; @@ -83,29 +90,31 @@ bool jw_put_int(JsonNode* jNode, char* key, int value) return false; if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "\"%s\":%d",key,value); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "\"%s\":%d", key, value); jw_inc_current_element_count(jNode); return true; } -bool jw_put_long(JsonNode* jNode, char* key, long value) +bool +jw_put_long(JsonNode * jNode, char *key, long value) { if (key == NULL) - return false; + return false; if (jw_get_current_element_count(jNode) < 0) - return false; + return false; if (jw_get_current_element_type(jNode) != JWOBJECT) - return false; + return false; if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "\"%s\":%ld",key,value); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "\"%s\":%ld", key, value); jw_inc_current_element_count(jNode); return true; } -bool jw_put_null(JsonNode* jNode, char* key) +bool +jw_put_null(JsonNode * jNode, char *key) { if (key == NULL) return false; @@ -115,13 +124,14 @@ bool jw_put_null(JsonNode* jNode, char* key) return false; if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "\"%s\":null",key); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "\"%s\":null", key); jw_inc_current_element_count(jNode); return true; } -bool jw_put_string_value(JsonNode* jNode, char* value) +bool +jw_put_string_value(JsonNode * jNode, char *value) { if (value == NULL) return false; @@ -129,69 +139,75 @@ bool jw_put_string_value(JsonNode* jNode, char* value) return false; if (jw_get_current_element_type(jNode) != JWARRAY) return false; - + if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "\"%s\"",value); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "\"%s\"", value); jw_inc_current_element_count(jNode); return true; } -bool jw_put_bool_value(JsonNode* jNode, bool value) +bool +jw_put_bool_value(JsonNode * jNode, bool value) { - return jw_put_int_value(jNode, value?1:0); + return jw_put_int_value(jNode, value ? 1 : 0); } -bool jw_put_int_value(JsonNode* jNode, int value) +bool +jw_put_int_value(JsonNode * jNode, int value) { if (jw_get_current_element_count(jNode) < 0) return false; if (jw_get_current_element_type(jNode) != JWARRAY) return false; - + if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "%d",value); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "%d", value); jw_inc_current_element_count(jNode); return true; } -bool jw_put_long_value(JsonNode* jNode, long value) +bool +jw_put_long_value(JsonNode * jNode, long value) { if (jw_get_current_element_count(jNode) < 0) - return false; + return false; if (jw_get_current_element_type(jNode) != JWARRAY) - return false; + return false; if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); - appendStringInfo(jNode->buf, "%ld",value); + appendStringInfoChar(jNode->buf, ','); + appendStringInfo(jNode->buf, "%ld", value); jw_inc_current_element_count(jNode); return true; } -bool jw_put_null_value(JsonNode* jNode) +bool +jw_put_null_value(JsonNode * jNode) { if (jw_get_current_element_count(jNode) < 0) return false; if (jw_get_current_element_type(jNode) != JWARRAY) return false; - + if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); + appendStringInfoChar(jNode->buf, ','); appendStringInfoString(jNode->buf, "null"); jw_inc_current_element_count(jNode); return true; } -bool jw_start_element(JsonNode* jNode, JWElementType element, char* key) +bool +jw_start_element(JsonNode * jNode, JWElementType element, char *key) { - char ch; + char ch; + if (jNode->stack_ptr >= MAX_STACK_DEPTH) return false; if (jw_get_current_element_count(jNode) > 0) - appendStringInfoChar(jNode->buf,','); + appendStringInfoChar(jNode->buf, ','); if (element == JWOBJECT) { @@ -205,35 +221,39 @@ bool jw_start_element(JsonNode* jNode, JWElementType element, char* key) return false; if (key == NULL) - appendStringInfoChar(jNode->buf,ch); + appendStringInfoChar(jNode->buf, ch); else - appendStringInfo(jNode->buf, "\"%s\": %c",key,ch); + appendStringInfo(jNode->buf, "\"%s\": %c", key, ch); jw_inc_current_element_count(jNode); jNode->stack[jNode->stack_ptr].elementCount = 0; - jNode->stack[jNode->stack_ptr++].elementType = element; + jNode->stack[jNode->stack_ptr++].elementType = element; return true; } -bool jw_start_array(JsonNode* jNode, char* key) +bool +jw_start_array(JsonNode * jNode, char *key) { if (jw_get_current_element_type(jNode) == JWARRAY) return jw_start_element(jNode, JWARRAY, NULL); return jw_start_element(jNode, JWARRAY, key); } -bool jw_start_object(JsonNode* jNode, char* key) +bool +jw_start_object(JsonNode * jNode, char *key) { if (jw_get_current_element_type(jNode) == JWARRAY) return jw_start_element(jNode, JWOBJECT, NULL); return jw_start_element(jNode, JWOBJECT, key); } -bool jw_end_element(JsonNode* jNode) +bool +jw_end_element(JsonNode * jNode) { - char ch; + char ch; JWElementType element; + if (jNode->stack_ptr <= 0) return false; /* pop the element from stack */ @@ -244,53 +264,60 @@ bool jw_end_element(JsonNode* jNode) ch = ']'; else return false; - appendStringInfoChar(jNode->buf,ch); + appendStringInfoChar(jNode->buf, ch); return true; } -bool jw_finish_document(JsonNode* jNode) +bool +jw_finish_document(JsonNode * jNode) { - while (jNode->stack_ptr > 0) { + while (jNode->stack_ptr > 0) + { if (!jw_end_element(jNode)) return false; } return true; } -char* jw_get_json_string(JsonNode* jNode) +char * +jw_get_json_string(JsonNode * jNode) { return jNode->buf->data; } -int jw_get_json_length(JsonNode* jNode) +int +jw_get_json_length(JsonNode * jNode) { return jNode->buf->len; } -void jw_destroy(JsonNode* jNode) +void +jw_destroy(JsonNode * jNode) { pfree(jNode->buf->data); pfree(jNode->buf); pfree(jNode); } -static inline int jw_get_current_element_count(JsonNode* jNode) +static inline int +jw_get_current_element_count(JsonNode * jNode) { if (jNode->stack_ptr <= 0) return -1; - return jNode->stack[jNode->stack_ptr -1].elementCount; + return jNode->stack[jNode->stack_ptr - 1].elementCount; } -static inline void jw_inc_current_element_count(JsonNode* jNode) +static inline void +jw_inc_current_element_count(JsonNode * jNode) { if (jNode->stack_ptr <= 0) return; - jNode->stack[jNode->stack_ptr -1].elementCount++; + jNode->stack[jNode->stack_ptr - 1].elementCount++; } -static inline JWElementType jw_get_current_element_type(JsonNode* jNode) +static inline JWElementType jw_get_current_element_type(JsonNode * jNode) { if (jNode->stack_ptr <= 0) return -1; - return jNode->stack[jNode->stack_ptr -1].elementType; + return jNode->stack[jNode->stack_ptr - 1].elementType; } diff --git a/src/utils/mmgr/mcxt.c b/src/utils/mmgr/mcxt.c index 7eb3d0954..2033e9d11 100644 --- a/src/utils/mmgr/mcxt.c +++ b/src/utils/mmgr/mcxt.c @@ -45,7 +45,9 @@ MemoryContext CurrentMemoryContext = NULL; */ MemoryContext TopMemoryContext = NULL; MemoryContext ErrorContext = NULL; -MemoryContext ProcessLoopContext = NULL; /* This context resets at every main loop iteration of a process */ +MemoryContext ProcessLoopContext = NULL; /* This context resets at every + * main loop iteration of a + * process */ MemoryContext CacheMemoryContext = NULL; MemoryContext MessageContext = NULL; MemoryContext QueryContext = NULL; @@ -969,7 +971,7 @@ repalloc(void *pointer, Size size) elog(ERROR, "invalid memory alloc request size %zu", size); /* pgpool hack by Muhammad Usama <m.usama@gmail.com> */ - if(pointer == NULL) + if (pointer == NULL) return palloc(size); context = GetMemoryChunkContext(pointer); diff --git a/src/utils/pcp/pcp_stream.c b/src/utils/pcp/pcp_stream.c index 29dca9726..e639bc361 100644 --- a/src/utils/pcp/pcp_stream.c +++ b/src/utils/pcp/pcp_stream.c @@ -1,7 +1,7 @@ /* * $Header$ * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2015 PgPool Global Development Group @@ -39,9 +39,9 @@ #include "utils/fe_ports.h" #endif -static int consume_pending_data(PCP_CONNECTION *pc, void *data, int len); -static int save_pending_data(PCP_CONNECTION *pc, void *data, int len); -static int pcp_check_fd(PCP_CONNECTION *pc); +static int consume_pending_data(PCP_CONNECTION * pc, void *data, int len); +static int save_pending_data(PCP_CONNECTION * pc, void *data, int len); +static int pcp_check_fd(PCP_CONNECTION * pc); /* -------------------------------- * pcp_open - allocate read & write buffers for PCP_CONNECTION @@ -52,30 +52,30 @@ static int pcp_check_fd(PCP_CONNECTION *pc); PCP_CONNECTION * pcp_open(int fd) { - PCP_CONNECTION *pc; + PCP_CONNECTION *pc; #ifndef POOL_PRIVATE - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); #endif - pc = (PCP_CONNECTION *)palloc0(sizeof(PCP_CONNECTION)); - /* initialize write buffer */ - pc->wbuf = palloc(WRITEBUFSZ); - pc->wbufsz = WRITEBUFSZ; - pc->wbufpo = 0; + pc = (PCP_CONNECTION *) palloc0(sizeof(PCP_CONNECTION)); + /* initialize write buffer */ + pc->wbuf = palloc(WRITEBUFSZ); + pc->wbufsz = WRITEBUFSZ; + pc->wbufpo = 0; - /* initialize pending data buffer */ - pc->hp = palloc(READBUFSZ); - pc->bufsz = READBUFSZ; - pc->po = 0; - pc->len = 0; + /* initialize pending data buffer */ + pc->hp = palloc(READBUFSZ); + pc->bufsz = READBUFSZ; + pc->po = 0; + pc->len = 0; #ifndef POOL_PRIVATE - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); #endif - pc->fd = fd; - return pc; + pc->fd = fd; + return pc; } /* -------------------------------- @@ -83,12 +83,12 @@ pcp_open(int fd) * -------------------------------- */ void -pcp_close(PCP_CONNECTION *pc) +pcp_close(PCP_CONNECTION * pc) { - close(pc->fd); - pfree(pc->wbuf); - pfree(pc->hp); - pfree(pc); + close(pc->fd); + pfree(pc->wbuf); + pfree(pc->hp); + pfree(pc); } /* -------------------------------- @@ -98,50 +98,50 @@ pcp_close(PCP_CONNECTION *pc) * -------------------------------- */ int -pcp_read(PCP_CONNECTION *pc, void *buf, int len) +pcp_read(PCP_CONNECTION * pc, void *buf, int len) { - static char readbuf[READBUFSZ]; + static char readbuf[READBUFSZ]; - int consume_size; - int readlen; + int consume_size; + int readlen; - consume_size = consume_pending_data(pc, buf, len); - len -= consume_size; - buf += consume_size; + consume_size = consume_pending_data(pc, buf, len); + len -= consume_size; + buf += consume_size; - while (len > 0) - { - if (pcp_check_fd(pc)) + while (len > 0) + { + if (pcp_check_fd(pc)) return -1; - readlen = read(pc->fd, readbuf, READBUFSZ); - if (readlen == -1) - { - if (errno == EAGAIN || errno == EINTR) - continue; + readlen = read(pc->fd, readbuf, READBUFSZ); + if (readlen == -1) + { + if (errno == EAGAIN || errno == EINTR) + continue; return -1; - } - else if (readlen == 0) + } + else if (readlen == 0) { return -1; } - if (len < readlen) - { - /* overrun. we need to save remaining data to pending buffer */ - if (save_pending_data(pc, readbuf+len, readlen-len)) - return -1; - memmove(buf, readbuf, len); - break; - } - - memmove(buf, readbuf, readlen); - buf += readlen; - len -= readlen; - } - - return 0; + if (len < readlen) + { + /* overrun. we need to save remaining data to pending buffer */ + if (save_pending_data(pc, readbuf + len, readlen - len)) + return -1; + memmove(buf, readbuf, len); + break; + } + + memmove(buf, readbuf, readlen); + buf += readlen; + len -= readlen; + } + + return 0; } /* -------------------------------- @@ -151,41 +151,41 @@ pcp_read(PCP_CONNECTION *pc, void *buf, int len) * -------------------------------- */ int -pcp_write(PCP_CONNECTION *pc, void *buf, int len) +pcp_write(PCP_CONNECTION * pc, void *buf, int len) { - int reqlen; + int reqlen; - if (len < 0) + if (len < 0) { - return -1; + return -1; } - /* check buffer size */ - reqlen = pc->wbufpo + len; + /* check buffer size */ + reqlen = pc->wbufpo + len; - if (reqlen > pc->wbufsz) - { - char *p; + if (reqlen > pc->wbufsz) + { + char *p; - reqlen = (reqlen/WRITEBUFSZ+1)*WRITEBUFSZ; + reqlen = (reqlen / WRITEBUFSZ + 1) * WRITEBUFSZ; #ifndef POOL_PRIVATE - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); #endif - p = repalloc(pc->wbuf, reqlen); + p = repalloc(pc->wbuf, reqlen); #ifndef POOL_PRIVATE - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); #endif - pc->wbuf = p; - pc->wbufsz = reqlen; - } + pc->wbuf = p; + pc->wbufsz = reqlen; + } - memcpy(pc->wbuf+pc->wbufpo, buf, len); - pc->wbufpo += len; + memcpy(pc->wbuf + pc->wbufpo, buf, len); + pc->wbufpo += len; - return 0; + return 0; } /* -------------------------------- @@ -195,57 +195,58 @@ pcp_write(PCP_CONNECTION *pc, void *buf, int len) * -------------------------------- */ int -pcp_flush(PCP_CONNECTION *pc) +pcp_flush(PCP_CONNECTION * pc) { - int sts; - int wlen; - int offset; - wlen = pc->wbufpo; - - if (wlen == 0) - { - return 0; - } - - offset = 0; - - for (;;) - { - errno = 0; - - sts = write(pc->fd, pc->wbuf + offset, wlen); - - if (sts > 0) - { - wlen -= sts; - - if (wlen == 0) - { - /* write completed */ - break; - } - - else if (wlen < 0) - { - return -1; - } - - else - { - /* need to write remaining data */ - offset += sts; - continue; - } - } - else if (errno == EAGAIN || errno == EINTR) - continue; - else - return -1; - } - - pc->wbufpo = 0; - - return 0; + int sts; + int wlen; + int offset; + + wlen = pc->wbufpo; + + if (wlen == 0) + { + return 0; + } + + offset = 0; + + for (;;) + { + errno = 0; + + sts = write(pc->fd, pc->wbuf + offset, wlen); + + if (sts > 0) + { + wlen -= sts; + + if (wlen == 0) + { + /* write completed */ + break; + } + + else if (wlen < 0) + { + return -1; + } + + else + { + /* need to write remaining data */ + offset += sts; + continue; + } + } + else if (errno == EAGAIN || errno == EINTR) + continue; + else + return -1; + } + + pc->wbufpo = 0; + + return 0; } /* -------------------------------- @@ -255,23 +256,23 @@ pcp_flush(PCP_CONNECTION *pc) * -------------------------------- */ static int -consume_pending_data(PCP_CONNECTION *pc, void *data, int len) +consume_pending_data(PCP_CONNECTION * pc, void *data, int len) { - int consume_size; + int consume_size; - if (pc->len <= 0) - return 0; + if (pc->len <= 0) + return 0; - consume_size = Min(len, pc->len); - memmove(data, pc->hp + pc->po, consume_size); - pc->len -= consume_size; + consume_size = Min(len, pc->len); + memmove(data, pc->hp + pc->po, consume_size); + pc->len -= consume_size; - if (pc->len <= 0) - pc->po = 0; - else - pc->po += consume_size; + if (pc->len <= 0) + pc->po = 0; + else + pc->po += consume_size; - return consume_size; + return consume_size; } /* -------------------------------- @@ -281,41 +282,41 @@ consume_pending_data(PCP_CONNECTION *pc, void *data, int len) * -------------------------------- */ static int -save_pending_data(PCP_CONNECTION *pc, void *data, int len) +save_pending_data(PCP_CONNECTION * pc, void *data, int len) { - int reqlen; - size_t realloc_size; - char *p; + int reqlen; + size_t realloc_size; + char *p; - /* to be safe */ - if (pc->len == 0) - pc->po = 0; + /* to be safe */ + if (pc->len == 0) + pc->po = 0; - reqlen = pc->po + pc->len + len; + reqlen = pc->po + pc->len + len; - /* pending buffer is enough? */ - if (reqlen > pc->bufsz) - { - /* too small, enlarge it */ - realloc_size = (reqlen/READBUFSZ+1)*READBUFSZ; + /* pending buffer is enough? */ + if (reqlen > pc->bufsz) + { + /* too small, enlarge it */ + realloc_size = (reqlen / READBUFSZ + 1) * READBUFSZ; #ifndef POOL_PRIVATE - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); #endif - p = repalloc(pc->hp, realloc_size); + p = repalloc(pc->hp, realloc_size); #ifndef POOL_PRIVATE - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); #endif - pc->bufsz = realloc_size; - pc->hp = p; - } + pc->bufsz = realloc_size; + pc->hp = p; + } - memmove(pc->hp + pc->po + pc->len, data, len); - pc->len += len; + memmove(pc->hp + pc->po + pc->len, data, len); + pc->len += len; - return 0; + return 0; } /* -------------------------------- @@ -325,40 +326,40 @@ save_pending_data(PCP_CONNECTION *pc, void *data, int len) * -------------------------------- */ static int -pcp_check_fd(PCP_CONNECTION *pc) +pcp_check_fd(PCP_CONNECTION * pc) { - fd_set readmask; - fd_set exceptmask; - int fd; - int fds; + fd_set readmask; + fd_set exceptmask; + int fd; + int fds; - fd = pc->fd; + fd = pc->fd; - for (;;) - { - FD_ZERO(&readmask); - FD_ZERO(&exceptmask); - FD_SET(fd, &readmask); - FD_SET(fd, &exceptmask); + for (;;) + { + FD_ZERO(&readmask); + FD_ZERO(&exceptmask); + FD_SET(fd, &readmask); + FD_SET(fd, &exceptmask); - fds = select(fd+1, &readmask, NULL, &exceptmask, NULL); + fds = select(fd + 1, &readmask, NULL, &exceptmask, NULL); - if (fds == -1) - { - if (errno == EAGAIN || errno == EINTR) - continue; + if (fds == -1) + { + if (errno == EAGAIN || errno == EINTR) + continue; - break; - } + break; + } - if (FD_ISSET(fd, &exceptmask)) - break; + if (FD_ISSET(fd, &exceptmask)) + break; - if (fds == 0) - break; + if (fds == 0) + break; - return 0; - } + return 0; + } - return -1; + return -1; } diff --git a/src/utils/pool_ip.c b/src/utils/pool_ip.c index 74d43c40e..de01770b6 100644 --- a/src/utils/pool_ip.c +++ b/src/utils/pool_ip.c @@ -52,19 +52,19 @@ #include "utils/pool_ip.h" #include "pool_config.h" #include "utils/elog.h" -static int rangeSockAddrAF_INET(const struct sockaddr_in * addr, - const struct sockaddr_in * netaddr, - const struct sockaddr_in * netmask); +static int rangeSockAddrAF_INET(const struct sockaddr_in *addr, + const struct sockaddr_in *netaddr, + const struct sockaddr_in *netmask); -static int rangeSockAddrAF_INET6(const struct sockaddr_in6 * addr, - const struct sockaddr_in6 * netaddr, - const struct sockaddr_in6 * netmask); +static int rangeSockAddrAF_INET6(const struct sockaddr_in6 *addr, + const struct sockaddr_in6 *netaddr, + const struct sockaddr_in6 *netmask); static int getaddrinfo_unix(const char *path, - const struct addrinfo * hintsp, - struct addrinfo ** result); + const struct addrinfo *hintsp, + struct addrinfo **result); -static int getnameinfo_unix(const struct sockaddr_un * sa, int salen, +static int getnameinfo_unix(const struct sockaddr_un *sa, int salen, char *node, int nodelen, char *service, int servicelen, int flags); @@ -73,7 +73,8 @@ static int getnameinfo_unix(const struct sockaddr_un * sa, int salen, * pool_getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets * caller MUST allocate NI_MAXHOST, NI_MAXSERV bytes for remote_host and remote_port */ -void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port) +void +pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port) { remote_host[0] = '\0'; remote_port[0] = '\0'; @@ -83,13 +84,14 @@ void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port) remote_port, NI_MAXSERV, (pool_config->log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) { - int ret = getnameinfo_all(&saddr->addr, saddr->salen, - remote_host, NI_MAXHOST, - remote_port, NI_MAXSERV, - NI_NUMERICHOST | NI_NUMERICSERV); + int ret = getnameinfo_all(&saddr->addr, saddr->salen, + remote_host, NI_MAXHOST, + remote_port, NI_MAXSERV, + NI_NUMERICHOST | NI_NUMERICSERV); + if (ret) ereport(WARNING, - (errmsg("getnameinfo failed with error: \"%s\"",gai_strerror(ret)))); + (errmsg("getnameinfo failed with error: \"%s\"", gai_strerror(ret)))); } } @@ -98,7 +100,7 @@ void pool_getnameinfo_all(SockAddr *saddr, char *remote_host, char *remote_port) */ int getaddrinfo_all(const char *hostname, const char *servname, - const struct addrinfo * hintp, struct addrinfo ** result) + const struct addrinfo *hintp, struct addrinfo **result) { /* not all versions of getaddrinfo() zero *result on failure */ *result = NULL; @@ -122,7 +124,7 @@ getaddrinfo_all(const char *hostname, const char *servname, * not safe to look at ai_family in the addrinfo itself. */ void -freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai) +freeaddrinfo_all(int hint_ai_family, struct addrinfo *ai) { if (hint_ai_family == AF_UNIX) { @@ -154,7 +156,7 @@ freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai) * guaranteed to be filled with something even on failure return. */ int -getnameinfo_all(const struct sockaddr_storage * addr, int salen, +getnameinfo_all(const struct sockaddr_storage *addr, int salen, char *node, int nodelen, char *service, int servicelen, int flags) @@ -176,7 +178,7 @@ getnameinfo_all(const struct sockaddr_storage * addr, int salen, flags); } - + if (rc != 0) { if (node) @@ -194,7 +196,7 @@ const char * gai_strerror(int errcode) { #ifdef HAVE_HSTRERROR - int hcode; + int hcode; switch (errcode) { @@ -250,9 +252,9 @@ gai_strerror(int errcode) default: return "Unknown server error"; } -#endif /* HAVE_HSTRERROR */ +#endif /* HAVE_HSTRERROR */ } -#endif /* HAVE_GAI_STRERROR */ +#endif /* HAVE_GAI_STRERROR */ /* @@ -264,8 +266,8 @@ gai_strerror(int errcode) * */ static int -getaddrinfo_unix(const char *path, const struct addrinfo * hintsp, - struct addrinfo ** result) +getaddrinfo_unix(const char *path, const struct addrinfo *hintsp, + struct addrinfo **result) { struct addrinfo hints; struct addrinfo *aip; @@ -330,7 +332,7 @@ getaddrinfo_unix(const char *path, const struct addrinfo * hintsp, * Convert an address to a hostname. */ static int -getnameinfo_unix(const struct sockaddr_un * sa, int salen, +getnameinfo_unix(const struct sockaddr_un *sa, int salen, char *node, int nodelen, char *service, int servicelen, int flags) @@ -366,9 +368,9 @@ getnameinfo_unix(const struct sockaddr_un * sa, int salen, static int -rangeSockAddrAF_INET(const struct sockaddr_in * addr, - const struct sockaddr_in * netaddr, - const struct sockaddr_in * netmask) +rangeSockAddrAF_INET(const struct sockaddr_in *addr, + const struct sockaddr_in *netaddr, + const struct sockaddr_in *netmask) { if (((addr->sin_addr.s_addr ^ netaddr->sin_addr.s_addr) & netmask->sin_addr.s_addr) == 0) @@ -379,9 +381,9 @@ rangeSockAddrAF_INET(const struct sockaddr_in * addr, static int -rangeSockAddrAF_INET6(const struct sockaddr_in6 * addr, - const struct sockaddr_in6 * netaddr, - const struct sockaddr_in6 * netmask) +rangeSockAddrAF_INET6(const struct sockaddr_in6 *addr, + const struct sockaddr_in6 *netaddr, + const struct sockaddr_in6 *netmask) { int i; @@ -404,7 +406,7 @@ rangeSockAddrAF_INET6(const struct sockaddr_in6 * addr, * Return value is 0 if okay, -1 if not. */ int -SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family) +SockAddr_cidr_mask(struct sockaddr_storage *mask, char *numbits, int family) { long bits; char *endptr; @@ -478,7 +480,7 @@ SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family) * that rangeSockAddr will look at. */ void -promote_v4_to_v6_addr(struct sockaddr_storage * addr) +promote_v4_to_v6_addr(struct sockaddr_storage *addr) { struct sockaddr_in addr4; struct sockaddr_in6 addr6; @@ -513,7 +515,7 @@ promote_v4_to_v6_addr(struct sockaddr_storage * addr) * that rangeSockAddr will look at. */ void -promote_v4_to_v6_mask(struct sockaddr_storage * addr) +promote_v4_to_v6_mask(struct sockaddr_storage *addr) { struct sockaddr_in addr4; struct sockaddr_in6 addr6; @@ -546,17 +548,17 @@ promote_v4_to_v6_mask(struct sockaddr_storage * addr) */ int rangeSockAddr(const struct sockaddr_storage *addr, - const struct sockaddr_storage *netaddr, - const struct sockaddr_storage *netmask) + const struct sockaddr_storage *netaddr, + const struct sockaddr_storage *netmask) { if (addr->ss_family == AF_INET) return rangeSockAddrAF_INET((const struct sockaddr_in *) addr, - (const struct sockaddr_in *) netaddr, - (const struct sockaddr_in *) netmask); + (const struct sockaddr_in *) netaddr, + (const struct sockaddr_in *) netmask); else if (addr->ss_family == AF_INET6) return rangeSockAddrAF_INET6((const struct sockaddr_in6 *) addr, - (const struct sockaddr_in6 *) netaddr, - (const struct sockaddr_in6 *) netmask); + (const struct sockaddr_in6 *) netaddr, + (const struct sockaddr_in6 *) netmask); else return 0; } @@ -602,6 +604,7 @@ run_ifaddr_callback(PgIfAddrCallback callback, void *cb_data, (*callback) (addr, mask, cb_data); } + /* * Enumerate the system's network interface addresses and call the callback * for each one. Returns 0 if successful, -1 if trouble. @@ -613,7 +616,7 @@ int pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data) { struct ifaddrs *ifa, - *l; + *l; if (getifaddrs(&ifa) < 0) return -1; diff --git a/src/utils/pool_params.c b/src/utils/pool_params.c index 9e8263f4c..db5f183e1 100644 --- a/src/utils/pool_params.c +++ b/src/utils/pool_params.c @@ -37,15 +37,16 @@ /* * initialize parameter structure */ -int pool_init_params(ParamStatus *params) +int +pool_init_params(ParamStatus * params) { - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); - params->num = 0; - params->names = palloc(MAX_PARAM_ITEMS*sizeof(char *)); - params->values = palloc(MAX_PARAM_ITEMS*sizeof(char *)); + params->num = 0; + params->names = palloc(MAX_PARAM_ITEMS * sizeof(char *)); + params->values = palloc(MAX_PARAM_ITEMS * sizeof(char *)); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); return 0; } @@ -53,23 +54,24 @@ int pool_init_params(ParamStatus *params) /* * discard parameter structure */ -void pool_discard_params(ParamStatus *params) +void +pool_discard_params(ParamStatus * params) { - int i; + int i; - for (i=0;i<params->num;i++) - { + for (i = 0; i < params->num; i++) + { pfree(params->names[i]); pfree(params->values[i]); - } - if(params->names) - pfree(params->names); - if(params->values) - pfree(params->values); - params->num = 0; - params->names = NULL; - params->values = NULL; - + } + if (params->names) + pfree(params->names); + if (params->values) + pfree(params->values); + params->num = 0; + params->names = NULL; + params->values = NULL; + } /* @@ -77,25 +79,27 @@ void pool_discard_params(ParamStatus *params) * also, pos is set * if not found, NULL is returned */ -char *pool_find_name(ParamStatus *params, char *name, int *pos) +char * +pool_find_name(ParamStatus * params, char *name, int *pos) { - int i; + int i; - for (i=0;i<params->num;i++) - { + for (i = 0; i < params->num; i++) + { if (!strcmp(name, params->names[i])) { *pos = i; return params->values[i]; } - } - return NULL; + } + return NULL; } /* * return name and value by index. */ -int pool_get_param(ParamStatus *params, int index, char **name, char **value) +int +pool_get_param(ParamStatus * params, int index, char **name, char **value) { if (index < 0 || index >= params->num) return -1; @@ -109,49 +113,51 @@ int pool_get_param(ParamStatus *params, int index, char **name, char **value) /* * add or replace name/value pair */ -int pool_add_param(ParamStatus *params, char *name, char *value) +int +pool_add_param(ParamStatus * params, char *name, char *value) { - int pos; - MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + int pos; + MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); - if (pool_find_name(params, name, &pos)) - { + if (pool_find_name(params, name, &pos)) + { /* name already exists */ if (strlen(params->values[pos]) < strlen(value)) { params->values[pos] = repalloc(params->values[pos], strlen(value) + 1); } strcpy(params->values[pos], value); - } - else - { - int num; + } + else + { + int num; /* add name/value pair */ if (params->num >= MAX_PARAM_ITEMS) { - ereport(ERROR, - (errmsg("add parameter failed"), - errdetail("no more room for num"))); + ereport(ERROR, + (errmsg("add parameter failed"), + errdetail("no more room for num"))); } num = params->num; params->names[num] = pstrdup(name); params->values[num] = pstrdup(value); params->num++; - } + } parser_set_param(name, value); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); return 0; } -void pool_param_debug_print(ParamStatus *params) +void +pool_param_debug_print(ParamStatus * params) { - int i; + int i; - for (i=0;i<params->num;i++) - { + for (i = 0; i < params->num; i++) + { ereport(DEBUG2, - (errmsg("No.%d: name: %s value: %s", i, params->names[i], params->values[i]))); + (errmsg("No.%d: name: %s value: %s", i, params->names[i], params->values[i]))); } } diff --git a/src/utils/pool_path.c b/src/utils/pool_path.c index 3c2c7c216..38220ac2c 100644 --- a/src/utils/pool_path.c +++ b/src/utils/pool_path.c @@ -38,15 +38,17 @@ static void trim_directory(char *path); static void trim_trailing_separator(char *path); -static int pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer, - size_t buflen, struct passwd ** result); +static int pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, + size_t buflen, struct passwd **result); + /* * get_parent_directory * * Modify the given string in-place to name the parent directory of the * named file. */ -void get_parent_directory(char *path) +void +get_parent_directory(char *path) { trim_directory(path); } @@ -57,10 +59,10 @@ void get_parent_directory(char *path) bool get_home_directory(char *buf, int bufsize) { - char pwdbuf[BUFSIZ]; + char pwdbuf[BUFSIZ]; struct passwd pwdstr; struct passwd *pwd = NULL; - + if (pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) != 0) return false; strlcpy(buf, pwd->pw_dir, bufsize); @@ -73,10 +75,10 @@ get_home_directory(char *buf, int bufsize) bool get_os_username(char *buf, int bufsize) { - char pwdbuf[BUFSIZ]; + char pwdbuf[BUFSIZ]; struct passwd pwdstr; struct passwd *pwd = NULL; - + if (pqGetpwuid(geteuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) != 0) return false; strlcpy(buf, pwd->pw_name, bufsize); @@ -91,16 +93,16 @@ get_os_username(char *buf, int bufsize) * behaviour, if it is not available or required. */ static int -pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer, - size_t buflen, struct passwd ** result) +pqGetpwuid(uid_t uid, struct passwd *resultbuf, char *buffer, + size_t buflen, struct passwd **result) { #if defined(HAVE_GETPWUID_R) - + #ifdef GETPWUID_R_5ARG /* POSIX version */ getpwuid_r(uid, resultbuf, buffer, buflen, result); #else - + /* * Early POSIX draft of getpwuid_r() returns 'struct passwd *'. * getpwuid_r(uid, resultbuf, buffer, buflen) @@ -108,11 +110,11 @@ pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer, *result = getpwuid_r(uid, resultbuf, buffer, buflen); #endif #else - + /* no getpwuid_r() available, just use getpwuid() */ *result = getpwuid(uid); #endif - + return (*result == NULL) ? -1 : 0; } @@ -123,9 +125,10 @@ pqGetpwuid(uid_t uid, struct passwd * resultbuf, char *buffer, * the last pathname component, and the slash just ahead of it --- but never * remove a leading slash. */ -static void trim_directory(char *path) +static void +trim_directory(char *path) { - char *p; + char *p; if (path[0] == '\0') return; @@ -154,14 +157,15 @@ static void trim_directory(char *path) * * ret_path can be the same as head, but not the same as tail. */ -void join_path_components(char *ret_path, const char *head, const char *tail) +void +join_path_components(char *ret_path, const char *head, const char *tail) { if (ret_path != head) StrNCpy(ret_path, head, MAXPGPATH); /* - * Remove any leading "." and ".." in the tail component, - * adjusting head as needed. + * Remove any leading "." and ".." in the tail component, adjusting head + * as needed. */ for (;;) { @@ -201,19 +205,21 @@ void join_path_components(char *ret_path, const char *head, const char *tail) * o remove trailing '.' * o process trailing '..' ourselves */ -void canonicalize_path(char *path) +void +canonicalize_path(char *path) { - char *p, *to_p; - bool was_sep = false; + char *p, + *to_p; + bool was_sep = false; /* - * Removing the trailing slash on a path means we never get ugly - * double trailing slashes. + * Removing the trailing slash on a path means we never get ugly double + * trailing slashes. */ trim_trailing_separator(path); /* - * Remove duplicate adjacent separators + * Remove duplicate adjacent separators */ p = path; to_p = p; @@ -233,7 +239,7 @@ void canonicalize_path(char *path) */ for (;;) { - int len = strlen(path); + int len = strlen(path); if (len > 2 && strcmp(path + len - 2, "/.") == 0) trim_directory(path); @@ -258,8 +264,8 @@ char * last_dir_separator(const char *filename) { const char *p, - *ret = NULL; - + *ret = NULL; + for (p = filename; *p; p++) if (IS_DIR_SEP(*p)) ret = p; @@ -271,9 +277,10 @@ last_dir_separator(const char *filename) * * trim off trailing slashes, but not a leading slash */ -static void trim_trailing_separator(char *path) +static void +trim_trailing_separator(char *path) { - char *p; + char *p; p = path + strlen(path); if (p > path) @@ -284,8 +291,8 @@ static void trim_trailing_separator(char *path) char * get_current_working_dir(void) { - char *buf = NULL; - size_t buflen = MAXPGPATH; + char *buf = NULL; + size_t buflen = MAXPGPATH; for (;;) { @@ -302,7 +309,7 @@ get_current_working_dir(void) } else { - int save_errno = errno; + int save_errno = errno; pfree(buf); errno = save_errno; @@ -313,6 +320,7 @@ get_current_working_dir(void) } return buf; } + /* * make_absolute_path * @@ -325,16 +333,18 @@ get_current_working_dir(void) * Logic borrowed from PostgreSQL source */ char * -make_absolute_path(const char *path, const char* base_dir) +make_absolute_path(const char *path, const char *base_dir) { - char *new; + char *new; + /* Returning null for null input is convenient for some callers */ if (path == NULL) return NULL; if (!is_absolute_path(path)) { - const char *cwd = NULL; + const char *cwd = NULL; + if (base_dir == NULL) { cwd = get_current_working_dir(); @@ -348,7 +358,7 @@ make_absolute_path(const char *path, const char* base_dir) sprintf(new, "%s/%s", cwd, path); if (!base_dir) - pfree((void*)cwd); + pfree((void *) cwd); } else { diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c index 2158c9f17..b5d22783d 100644 --- a/src/utils/pool_process_reporting.c +++ b/src/utils/pool_process_reporting.c @@ -33,24 +33,25 @@ #include <netinet/in.h> -void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, - short num_fields, char **field_names) +void +send_row_description(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, + short num_fields, char **field_names) { static char *cursorname = "blank"; - static int oid = 0; + static int oid = 0; static short fsize = -1; - static int mod = 0; - short n; - int i; - short s; - int len; - short colnum; + static int mod = 0; + short n; + int i; + short s; + int len; + short colnum; if (MAJOR(backend) == PROTO_MAJOR_V2) { /* cursor response */ pool_write(frontend, "P", 1); - pool_write(frontend, cursorname, strlen(cursorname)+1); + pool_write(frontend, cursorname, strlen(cursorname) + 1); } /* row description */ @@ -58,15 +59,18 @@ void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe if (MAJOR(backend) == PROTO_MAJOR_V3) { - /* information about computed byte in section "RowDescription (B)" here: - * http://www.postgresql.org/docs/current/static/protocol-message-formats.html */ + /* + * information about computed byte in section "RowDescription (B)" + * here: + * http://www.postgresql.org/docs/current/static/protocol-message-formats.html + */ - len = 6; /* int32 + int16 */ + len = 6; /* int32 + int16 */ - for (i=0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { /* String + '\0' + 3* int32 + 3* int16 */ - len += strlen(field_names[i]) +1 +18; + len += strlen(field_names[i]) + 1 + 18; } len = htonl(len); @@ -76,9 +80,9 @@ void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe n = htons(num_fields); pool_write(frontend, &n, sizeof(short)); - for (i=0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { - pool_write(frontend, field_names[i], strlen(field_names[i])+1); /* field name */ + pool_write(frontend, field_names[i], strlen(field_names[i]) + 1); /* field name */ if (MAJOR(backend) == PROTO_MAJOR_V3) { @@ -87,10 +91,10 @@ void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe pool_write(frontend, &colnum, sizeof(colnum)); /* column number */ } - pool_write(frontend, &oid, sizeof(oid)); /* data type oid */ + pool_write(frontend, &oid, sizeof(oid)); /* data type oid */ s = htons(fsize); - pool_write(frontend, &s, sizeof(fsize)); /* field size */ - pool_write(frontend, &mod, sizeof(mod)); /* modifier */ + pool_write(frontend, &s, sizeof(fsize)); /* field size */ + pool_write(frontend, &mod, sizeof(mod)); /* modifier */ if (MAJOR(backend) == PROTO_MAJOR_V3) { @@ -107,29 +111,34 @@ void send_row_description(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backe * if the num_row is passed with a -ve value it is not included * to the command complete message */ -void send_complete_and_ready(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend,const char* message ,const int num_rows) +void +send_complete_and_ready(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *message, const int num_rows) { - int len; - int msg_len; - char msg[16]; + int len; + int msg_len; + char msg[16]; if (num_rows >= 0) - msg_len = snprintf(msg, 16, "%s %d", message,num_rows); + msg_len = snprintf(msg, 16, "%s %d", message, num_rows); else msg_len = snprintf(msg, 16, "%s", message); - /* if we had more than 16 bytes, including '\0', the string was truncatured - * shouldn't happen though, as it would means more than "SELECT 99999999" */ - if (msg_len > 15) msg_len = 15; + /* + * if we had more than 16 bytes, including '\0', the string was + * truncatured shouldn't happen though, as it would means more than + * "SELECT 99999999" + */ + if (msg_len > 15) + msg_len = 15; /* complete command response */ pool_write(frontend, "C", 1); if (MAJOR(backend) == PROTO_MAJOR_V3) { - len = htonl(4 + strlen(msg)+1); + len = htonl(4 + strlen(msg) + 1); pool_write(frontend, &len, sizeof(len)); } - pool_write(frontend, msg, strlen(msg)+1); + pool_write(frontend, msg, strlen(msg) + 1); /* ready for query */ pool_write(frontend, "Z", 1); @@ -143,10 +152,12 @@ void send_complete_and_ready(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *ba pool_flush(frontend); } -POOL_REPORT_CONFIG* get_config(int *nrows) +POOL_REPORT_CONFIG * +get_config(int *nrows) { - int i, j; - int len; + int i, + j; + int len; /* * Report data buffer. @@ -154,12 +165,14 @@ POOL_REPORT_CONFIG* get_config(int *nrows) * In addition, we need MAX_NUM_BACKENDS*4 * for backend descriptions. */ -#define MAXITEMS (256 + MAX_NUM_BACKENDS*4) +#define MAXITEMS (256 + MAX_NUM_BACKENDS*4) - POOL_REPORT_CONFIG* status = palloc0(MAXITEMS * sizeof(POOL_REPORT_CONFIG)); + POOL_REPORT_CONFIG *status = palloc0(MAXITEMS * sizeof(POOL_REPORT_CONFIG)); - /* we initialize the array with NULL values so when looping - * on it, we can use it as stop condition */ + /* + * we initialize the array with NULL values so when looping on it, we can + * use it as stop condition + */ i = 0; @@ -302,17 +315,17 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].desc, "printf-style string to output at beginning of each log line", POOLCONFIG_MAXDESCLEN); i++; - StrNCpy(status[i].name, "log_error_verbosity", POOLCONFIG_MAXNAMELEN); + StrNCpy(status[i].name, "log_error_verbosity", POOLCONFIG_MAXNAMELEN); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_error_verbosity); StrNCpy(status[i].desc, "controls how much detail about error should be emitted", POOLCONFIG_MAXDESCLEN); i++; - StrNCpy(status[i].name, "client_min_messages", POOLCONFIG_MAXNAMELEN); + StrNCpy(status[i].name, "client_min_messages", POOLCONFIG_MAXNAMELEN); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->client_min_messages); StrNCpy(status[i].desc, "controls which message should be sent to client", POOLCONFIG_MAXDESCLEN); i++; - StrNCpy(status[i].name, "log_min_messages", POOLCONFIG_MAXNAMELEN); + StrNCpy(status[i].name, "log_min_messages", POOLCONFIG_MAXNAMELEN); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->log_min_messages); StrNCpy(status[i].desc, "controls which message should be emitted to server log", POOLCONFIG_MAXDESCLEN); i++; @@ -349,7 +362,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) /* - Syslog specific - */ StrNCpy(status[i].name, "syslog_facility", POOLCONFIG_MAXNAMELEN); - snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "LOCAL%d", (pool_config->syslog_facility/8) - 16); + snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "LOCAL%d", (pool_config->syslog_facility / 8) - 16); StrNCpy(status[i].desc, "syslog local faclity", POOLCONFIG_MAXDESCLEN); i++; @@ -379,12 +392,12 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "reset_query_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_reset_queries;j++) + for (j = 0; j < pool_config->num_reset_queries; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->reset_query_list[j], len); len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); - if (j != pool_config->num_reset_queries-1) + if (j != pool_config->num_reset_queries - 1) strncat(status[i].value, ";", len); } StrNCpy(status[i].desc, "queries issued at the end of session", POOLCONFIG_MAXDESCLEN); @@ -437,12 +450,12 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "white_function_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_white_function_list;j++) + for (j = 0; j < pool_config->num_white_function_list; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->white_function_list[j], len); len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); - if (j != pool_config->num_white_function_list-1) + if (j != pool_config->num_white_function_list - 1) strncat(status[i].value, ",", len); } StrNCpy(status[i].desc, "functions those do not write to database", POOLCONFIG_MAXDESCLEN); @@ -450,12 +463,12 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "black_function_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_black_function_list;j++) + for (j = 0; j < pool_config->num_black_function_list; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->black_function_list[j], len); len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); - if (j != pool_config->num_black_function_list-1) + if (j != pool_config->num_black_function_list - 1) strncat(status[i].value, ",", len); } StrNCpy(status[i].desc, "functions those write to database", POOLCONFIG_MAXDESCLEN); @@ -463,12 +476,12 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "black_query_pattern_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_black_query_pattern_list;j++) + for (j = 0; j < pool_config->num_black_query_pattern_list; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->black_query_pattern_list[j], len); len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); - if (j != pool_config->num_black_query_pattern_list-1) + if (j != pool_config->num_black_query_pattern_list - 1) strncat(status[i].value, ";", len); } StrNCpy(status[i].desc, "query patterns that should be sent to primary node", POOLCONFIG_MAXDESCLEN); @@ -501,7 +514,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->sr_check_user); StrNCpy(status[i].desc, "sr check user", POOLCONFIG_MAXDESCLEN); i++; -#ifdef NOT_USED /* for security reason */ +#ifdef NOT_USED /* for security reason */ StrNCpy(status[i].name, "sr_check_password", POOLCONFIG_MAXNAMELEN); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->sr_check_password); StrNCpy(status[i].desc, "sr check password", POOLCONFIG_MAXDESCLEN); @@ -554,7 +567,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->health_check_user); StrNCpy(status[i].desc, "health check user", POOLCONFIG_MAXDESCLEN); i++; -#ifdef NOT_USED /* for security reason */ +#ifdef NOT_USED /* for security reason */ StrNCpy(status[i].name, "health_check_password", POOLCONFIG_MAXNAMELEN); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->health_check_password); StrNCpy(status[i].desc, "health check password", POOLCONFIG_MAXDESCLEN); @@ -791,12 +804,12 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "wd_monitoring_interfaces_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_wd_monitoring_interfaces_list;j++) + for (j = 0; j < pool_config->num_wd_monitoring_interfaces_list; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->wd_monitoring_interfaces_list[j], len); len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); - if (j != pool_config->num_wd_monitoring_interfaces_list-1) + if (j != pool_config->num_wd_monitoring_interfaces_list - 1) strncat(status[i].value, ",", len); } StrNCpy(status[i].desc, "interfaces to monitor by watchdog", POOLCONFIG_MAXDESCLEN); @@ -878,7 +891,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "white_memqcache_table_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_white_memqcache_table_list;j++) + for (j = 0; j < pool_config->num_white_memqcache_table_list; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->white_memqcache_table_list[j], len); @@ -891,7 +904,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) StrNCpy(status[i].name, "black_memqcache_table_list", POOLCONFIG_MAXNAMELEN); *(status[i].value) = '\0'; - for (j=0;j<pool_config->num_black_memqcache_table_list;j++) + for (j = 0; j < pool_config->num_black_memqcache_table_list; j++) { len = POOLCONFIG_MAXVALLEN - strlen(status[i].value); strncat(status[i].value, pool_config->black_memqcache_table_list[j], len); @@ -920,7 +933,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) i++; snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_weight%d", j); - snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%f", BACKEND_INFO(j).backend_weight/RAND_MAX); + snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%f", BACKEND_INFO(j).backend_weight / RAND_MAX); snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "weight of backend #%d", j); i++; @@ -930,7 +943,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) i++; snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "backend_status%d", j); - snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s",backend_status_to_str(&BACKEND_INFO(j)) ); + snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", backend_status_to_str(&BACKEND_INFO(j))); snprintf(status[i].desc, POOLCONFIG_MAXDESCLEN, "status of backend #%d", j); i++; @@ -967,7 +980,7 @@ POOL_REPORT_CONFIG* get_config(int *nrows) } - for (j =0; j < pool_config->num_hb_if; j++) + for (j = 0; j < pool_config->num_hb_if; j++) { snprintf(status[i].name, POOLCONFIG_MAXNAMELEN, "heartbeat_device%d", j); snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", WD_HB_IF(j).if_name); @@ -989,121 +1002,124 @@ POOL_REPORT_CONFIG* get_config(int *nrows) return status; } -void send_config_var_detail_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* name, const char* value, const char* description) +void +send_config_var_detail_row(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *name, const char *value, const char *description) { - int size; - int hsize; + int size; + int hsize; static short num_fields = 3; if (MAJOR(backend) == PROTO_MAJOR_V2) { - int nbytes = (num_fields + 7)/8; + int nbytes = (num_fields + 7) / 8; static unsigned char nullmap[2] = {0xff, 0xff}; /* ascii row */ pool_write(frontend, "D", 1); pool_write_and_flush(frontend, nullmap, nbytes); - + size = strlen(name); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)name, size); - + pool_write(frontend, (void *) name, size); + size = strlen(value); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)value, size); - + pool_write(frontend, (void *) value, size); + size = strlen(description); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)description, size); + pool_write(frontend, (void *) description, size); } else { - short s; + short s; pool_write(frontend, "D", 1); - size = 6; /* int32 + int16; */ - size += 4 + strlen(name); /* int32 + data; */ - size += 4 + strlen(value); /* int32 + data; */ - size += 4 + strlen(description); /* int32 + data; */ + size = 6; /* int32 + int16; */ + size += 4 + strlen(name); /* int32 + data; */ + size += 4 + strlen(value); /* int32 + data; */ + size += 4 + strlen(description); /* int32 + data; */ hsize = htonl(size); pool_write(frontend, &hsize, sizeof(hsize)); s = htons(num_fields); pool_write(frontend, &s, sizeof(s)); - + size = strlen(name); hsize = htonl(size); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)name, size); + pool_write(frontend, (void *) name, size); size = strlen(value); hsize = htonl(size); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)value, size); + pool_write(frontend, (void *) value, size); size = strlen(description); hsize = htonl(size); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)description, size); + pool_write(frontend, (void *) description, size); } } -void send_config_var_value_only_row(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend, const char* value) +void +send_config_var_value_only_row(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend, const char *value) { - int size; - int hsize; + int size; + int hsize; static short num_fields = 1; - + if (MAJOR(backend) == PROTO_MAJOR_V2) { - - int nbytes = (num_fields + 7)/8; + + int nbytes = (num_fields + 7) / 8; static unsigned char nullmap[2] = {0xff, 0xff}; /* ascii row */ pool_write(frontend, "D", 1); pool_write_and_flush(frontend, nullmap, nbytes); - + size = strlen(value); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)value, size); + pool_write(frontend, (void *) value, size); } else { - short s; - + short s; + pool_write(frontend, "D", 1); - size = 6; /* int32 + int16; */ - size += 4 + strlen(value); /* int32 + data; */ + size = 6; /* int32 + int16; */ + size += 4 + strlen(value); /* int32 + data; */ hsize = htonl(size); pool_write(frontend, &hsize, sizeof(hsize)); s = htons(num_fields); pool_write(frontend, &s, sizeof(s)); - + size = strlen(value); hsize = htonl(size); pool_write(frontend, &hsize, sizeof(hsize)); - pool_write(frontend, (void*)value, size); + pool_write(frontend, (void *) value, size); } } -void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +config_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { static char *field_names[] = {"item", "value", "description"}; static unsigned char nullmap[2] = {0xff, 0xff}; static short num_fields = 3; - short s; - int nbytes = (num_fields + 7)/8; - int len; - int nrows; - int size; - int hsize; - int i; + short s; + int nbytes = (num_fields + 7) / 8; + int len; + int nrows; + int size; + int hsize; + int i; POOL_REPORT_CONFIG *status = get_config(&nrows); @@ -1112,23 +1128,23 @@ void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) if (MAJOR(backend) == PROTO_MAJOR_V2) { /* ascii row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { pool_write(frontend, "D", 1); pool_write_and_flush(frontend, nullmap, nbytes); size = strlen(status[i].name); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, status[i].name, size); size = strlen(status[i].value); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, status[i].value, size); size = strlen(status[i].desc); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, status[i].desc, size); } @@ -1136,13 +1152,13 @@ void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) else { /* data row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - len += 4 + strlen(status[i].name); /* int32 + data; */ + len = 6; /* int32 + int16; */ + len += 4 + strlen(status[i].name); /* int32 + data; */ len += 4 + strlen(status[i].value); /* int32 + data; */ - len += 4 + strlen(status[i].desc); /* int32 + data; */ + len += 4 + strlen(status[i].desc); /* int32 + data; */ len = htonl(len); pool_write(frontend, &len, sizeof(len)); s = htons(num_fields); @@ -1162,31 +1178,32 @@ void config_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) } } - send_complete_and_ready(frontend, backend,"SELECT", nrows); + send_complete_and_ready(frontend, backend, "SELECT", nrows); pfree(status); } -POOL_REPORT_NODES* get_nodes(int *nrows) +POOL_REPORT_NODES * +get_nodes(int *nrows) { - int i; - POOL_REPORT_NODES* nodes = palloc(NUM_BACKENDS * sizeof(POOL_REPORT_NODES)); + int i; + POOL_REPORT_NODES *nodes = palloc(NUM_BACKENDS * sizeof(POOL_REPORT_NODES)); BackendInfo *bi = NULL; POOL_SESSION_CONTEXT *session_context = pool_get_session_context(false); - struct tm tm; + struct tm tm; - for (i = 0; i < NUM_BACKENDS; i++) + for (i = 0; i < NUM_BACKENDS; i++) { - bi = pool_get_node_info(i); + bi = pool_get_node_info(i); - snprintf(nodes[i].node_id, POOLCONFIG_MAXIDLEN, "%d", i); - StrNCpy(nodes[i].hostname, bi->backend_hostname, strlen(bi->backend_hostname)+1); - snprintf(nodes[i].port, POOLCONFIG_MAXPORTLEN, "%d", bi->backend_port); - snprintf(nodes[i].status, POOLCONFIG_MAXSTATLEN, "%s", backend_status_to_str(bi)); - snprintf(nodes[i].lb_weight, POOLCONFIG_MAXWEIGHTLEN, "%f", bi->backend_weight/RAND_MAX); - snprintf(nodes[i].select, POOLCONFIG_MAXWEIGHTLEN, UINT64_FORMAT, stat_get_select_count(i)); - snprintf(nodes[i].load_balance_node, POOLCONFIG_MAXWEIGHTLEN, "%s", - (session_context->load_balance_node_id == i)? "true":"false"); + snprintf(nodes[i].node_id, POOLCONFIG_MAXIDLEN, "%d", i); + StrNCpy(nodes[i].hostname, bi->backend_hostname, strlen(bi->backend_hostname) + 1); + snprintf(nodes[i].port, POOLCONFIG_MAXPORTLEN, "%d", bi->backend_port); + snprintf(nodes[i].status, POOLCONFIG_MAXSTATLEN, "%s", backend_status_to_str(bi)); + snprintf(nodes[i].lb_weight, POOLCONFIG_MAXWEIGHTLEN, "%f", bi->backend_weight / RAND_MAX); + snprintf(nodes[i].select, POOLCONFIG_MAXWEIGHTLEN, UINT64_FORMAT, stat_get_select_count(i)); + snprintf(nodes[i].load_balance_node, POOLCONFIG_MAXWEIGHTLEN, "%s", + (session_context->load_balance_node_id == i) ? "true" : "false"); snprintf(nodes[i].delay, POOLCONFIG_MAXWEIGHTLEN, "%d", 0); @@ -1220,78 +1237,79 @@ POOL_REPORT_NODES* get_nodes(int *nrows) return nodes; } -void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +nodes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { - static char *field_names[] = {"node_id","hostname", "port", "status", "lb_weight", "role", "select_cnt", "load_balance_node", "replication_delay", "last_status_change"}; - short num_fields = sizeof(field_names)/sizeof(char *); - int i; - short s; - int len; - int nrows; - int size; - int hsize; + static char *field_names[] = {"node_id", "hostname", "port", "status", "lb_weight", "role", "select_cnt", "load_balance_node", "replication_delay", "last_status_change"}; + short num_fields = sizeof(field_names) / sizeof(char *); + int i; + short s; + int len; + int nrows; + int size; + int hsize; static unsigned char nullmap[2] = {0xff, 0xff}; - int nbytes = (num_fields + 7)/8; + int nbytes = (num_fields + 7) / 8; - POOL_REPORT_NODES* nodes = get_nodes(&nrows); + POOL_REPORT_NODES *nodes = get_nodes(&nrows); send_row_description(frontend, backend, num_fields, field_names); if (MAJOR(backend) == PROTO_MAJOR_V2) { /* ascii row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { pool_write(frontend, "D", 1); pool_write_and_flush(frontend, nullmap, nbytes); size = strlen(nodes[i].node_id); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].node_id, size); size = strlen(nodes[i].hostname); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].hostname, size); size = strlen(nodes[i].port); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].port, size); size = strlen(nodes[i].status); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].status, size); size = strlen(nodes[i].lb_weight); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].lb_weight, size); size = strlen(nodes[i].role); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].role, size); size = strlen(nodes[i].select); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].select, size); size = strlen(nodes[i].load_balance_node); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].load_balance_node, size); size = strlen(nodes[i].delay); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].delay, size); size = strlen(nodes[i].last_status_change); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, nodes[i].last_status_change, size); } @@ -1299,20 +1317,20 @@ void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) else { /* data row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - len += 4 + strlen(nodes[i].node_id); /* int32 + data; */ - len += 4 + strlen(nodes[i].hostname); /* int32 + data; */ - len += 4 + strlen(nodes[i].port); /* int32 + data; */ - len += 4 + strlen(nodes[i].status); /* int32 + data; */ - len += 4 + strlen(nodes[i].lb_weight); /* int32 + data; */ - len += 4 + strlen(nodes[i].role); /* int32 + data; */ - len += 4 + strlen(nodes[i].select); /* int32 + data; */ - len += 4 + strlen(nodes[i].load_balance_node); /* int32 + data; */ - len += 4 + strlen(nodes[i].delay); /* int32 + data; */ - len += 4 + strlen(nodes[i].last_status_change); /* int32 + data; */ + len = 6; /* int32 + int16; */ + len += 4 + strlen(nodes[i].node_id); /* int32 + data; */ + len += 4 + strlen(nodes[i].hostname); /* int32 + data; */ + len += 4 + strlen(nodes[i].port); /* int32 + data; */ + len += 4 + strlen(nodes[i].status); /* int32 + data; */ + len += 4 + strlen(nodes[i].lb_weight); /* int32 + data; */ + len += 4 + strlen(nodes[i].role); /* int32 + data; */ + len += 4 + strlen(nodes[i].select); /* int32 + data; */ + len += 4 + strlen(nodes[i].load_balance_node); /* int32 + data; */ + len += 4 + strlen(nodes[i].delay); /* int32 + data; */ + len += 4 + strlen(nodes[i].last_status_change); /* int32 + data; */ len = htonl(len); pool_write(frontend, &len, sizeof(len)); s = htons(num_fields); @@ -1366,18 +1384,22 @@ void nodes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) } -POOL_REPORT_POOLS* get_pools(int *nrows) +POOL_REPORT_POOLS * +get_pools(int *nrows) { - int child, pool, poolBE, backend_id; + int child, + pool, + poolBE, + backend_id; - ProcessInfo *pi = NULL; - int proc_id; + ProcessInfo *pi = NULL; + int proc_id; - int lines = 0; + int lines = 0; - POOL_REPORT_POOLS* pools = palloc( - pool_config->num_init_children * pool_config->max_pool * NUM_BACKENDS * sizeof(POOL_REPORT_POOLS) - ); + POOL_REPORT_POOLS *pools = palloc( + pool_config->num_init_children * pool_config->max_pool * NUM_BACKENDS * sizeof(POOL_REPORT_POOLS) + ); for (child = 0; child < pool_config->num_init_children; child++) { @@ -1388,7 +1410,7 @@ POOL_REPORT_POOLS* get_pools(int *nrows) { for (backend_id = 0; backend_id < NUM_BACKENDS; backend_id++) { - poolBE = pool*MAX_NUM_BACKENDS+backend_id; + poolBE = pool * MAX_NUM_BACKENDS + backend_id; pools[lines].pool_pid = proc_id; pools[lines].start_time = pi->start_time; pools[lines].pool_id = pool; @@ -1415,45 +1437,48 @@ POOL_REPORT_POOLS* get_pools(int *nrows) lines++; } } - } + } *nrows = lines; return pools; } -void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +pools_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { static short num_fields = 12; static char *field_names[] = {"pool_pid", "start_time", "pool_id", "backend_id", "database", "username", "create_time", - "majorversion", "minorversion", "pool_counter", "pool_backendpid", "pool_connected"}; - short s; - int len; - int i; + "majorversion", "minorversion", "pool_counter", "pool_backendpid", "pool_connected"}; + short s; + int len; + int i; static unsigned char nullmap[2] = {0xff, 0xff}; - int nbytes = (num_fields + 7)/8; - int nrows; - int size; - int hsize; - char proc_pid[16]; - char pool_id[16]; - char proc_start_time[20]; - char proc_create_time[20]; - char majorversion[5]; - char minorversion[5]; - char pool_counter[16]; - char backend_id[16]; - char backend_pid[16]; - char connected[2]; - - POOL_REPORT_POOLS *pools = get_pools(&nrows); + int nbytes = (num_fields + 7) / 8; + int nrows; + int size; + int hsize; + char proc_pid[16]; + char pool_id[16]; + char proc_start_time[20]; + char proc_create_time[20]; + char majorversion[5]; + char minorversion[5]; + char pool_counter[16]; + char backend_id[16]; + char backend_pid[16]; + char connected[2]; + + POOL_REPORT_POOLS *pools = get_pools(&nrows); send_row_description(frontend, backend, num_fields, field_names); - if (MAJOR(backend) == PROTO_MAJOR_V2) hsize = 4; - else hsize = 0; + if (MAJOR(backend) == PROTO_MAJOR_V2) + hsize = 4; + else + hsize = 0; /* ascii row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { snprintf(proc_pid, sizeof(proc_pid), "%d", pools[i].pool_pid); snprintf(pool_id, sizeof(pool_id), "%d", pools[i].pool_id); @@ -1480,20 +1505,20 @@ void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) else { pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - len += 4 + strlen(proc_pid); /* int32 + data */ - len += 4 + strlen(proc_start_time); /* int32 + data */ - len += 4 + strlen(pool_id); /* int32 + data */ - len += 4 + strlen(backend_id); /* int32 + data */ - len += 4 + strlen(pools[i].database); /* int32 + data */ - len += 4 + strlen(pools[i].username); /* int32 + data */ - len += 4 + strlen(proc_create_time); /* int32 + data */ - len += 4 + strlen(majorversion); /* int32 + data */ - len += 4 + strlen(minorversion); /* int32 + data */ - len += 4 + strlen(pool_counter); /* int32 + data */ - len += 4 + strlen(backend_pid); /* int32 + data */ - len += 4 + strlen(connected); /* int32 + data */ - + len = 6; /* int32 + int16; */ + len += 4 + strlen(proc_pid); /* int32 + data */ + len += 4 + strlen(proc_start_time); /* int32 + data */ + len += 4 + strlen(pool_id); /* int32 + data */ + len += 4 + strlen(backend_id); /* int32 + data */ + len += 4 + strlen(pools[i].database); /* int32 + data */ + len += 4 + strlen(pools[i].username); /* int32 + data */ + len += 4 + strlen(proc_create_time); /* int32 + data */ + len += 4 + strlen(majorversion); /* int32 + data */ + len += 4 + strlen(minorversion); /* int32 + data */ + len += 4 + strlen(pool_counter); /* int32 + data */ + len += 4 + strlen(backend_pid); /* int32 + data */ + len += 4 + strlen(connected); /* int32 + data */ + len = htonl(len); pool_write(frontend, &len, sizeof(len)); s = htons(num_fields); @@ -1501,62 +1526,62 @@ void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) } len = strlen(proc_pid); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, proc_pid, len); len = strlen(proc_start_time); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, proc_start_time, len); len = strlen(pool_id); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, pool_id, len); len = strlen(backend_id); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, backend_id, len); len = strlen(pools[i].database); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, pools[i].database, len); len = strlen(pools[i].username); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, pools[i].username, len); len = strlen(proc_create_time); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, proc_create_time, len); len = strlen(majorversion); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, majorversion, len); len = strlen(minorversion); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, minorversion, len); len = strlen(pool_counter); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, pool_counter, len); len = strlen(backend_pid); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, backend_pid, len); len = strlen(connected); - size = htonl(len+hsize); + size = htonl(len + hsize); pool_write(frontend, &size, sizeof(size)); pool_write(frontend, connected, len); } @@ -1566,98 +1591,100 @@ void pools_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) pfree(pools); } -POOL_REPORT_PROCESSES* get_processes(int *nrows) +POOL_REPORT_PROCESSES * +get_processes(int *nrows) { - int child; - int pool; - int poolBE; - ProcessInfo *pi = NULL; - int proc_id; + int child; + int pool; + int poolBE; + ProcessInfo *pi = NULL; + int proc_id; - POOL_REPORT_PROCESSES* processes = palloc(pool_config->num_init_children * sizeof(POOL_REPORT_PROCESSES)); + POOL_REPORT_PROCESSES *processes = palloc(pool_config->num_init_children * sizeof(POOL_REPORT_PROCESSES)); for (child = 0; child < pool_config->num_init_children; child++) - { + { proc_id = process_info[child].pid; - pi = pool_get_process_info(proc_id); - - snprintf(processes[child].pool_pid, POOLCONFIG_MAXCOUNTLEN, "%d", proc_id); - strftime(processes[child].start_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); - StrNCpy(processes[child].database, "", POOLCONFIG_MAXIDENTLEN); - StrNCpy(processes[child].username, "", POOLCONFIG_MAXIDENTLEN); - StrNCpy(processes[child].create_time, "", POOLCONFIG_MAXDATELEN); - StrNCpy(processes[child].pool_counter, "", POOLCONFIG_MAXCOUNTLEN); - - for (pool = 0; pool < pool_config->max_pool; pool++) - { - poolBE = pool*MAX_NUM_BACKENDS; - if (pi->connection_info[poolBE].connected && strlen(pi->connection_info[poolBE].database) > 0 && strlen(pi->connection_info[poolBE].user) > 0) - { - StrNCpy(processes[child].database, pi->connection_info[poolBE].database, POOLCONFIG_MAXIDENTLEN); - StrNCpy(processes[child].username, pi->connection_info[poolBE].user, POOLCONFIG_MAXIDENTLEN); - strftime(processes[child].create_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].create_time)); - snprintf(processes[child].pool_counter, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[poolBE].counter); - } - } - } + pi = pool_get_process_info(proc_id); + + snprintf(processes[child].pool_pid, POOLCONFIG_MAXCOUNTLEN, "%d", proc_id); + strftime(processes[child].start_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->start_time)); + StrNCpy(processes[child].database, "", POOLCONFIG_MAXIDENTLEN); + StrNCpy(processes[child].username, "", POOLCONFIG_MAXIDENTLEN); + StrNCpy(processes[child].create_time, "", POOLCONFIG_MAXDATELEN); + StrNCpy(processes[child].pool_counter, "", POOLCONFIG_MAXCOUNTLEN); + + for (pool = 0; pool < pool_config->max_pool; pool++) + { + poolBE = pool * MAX_NUM_BACKENDS; + if (pi->connection_info[poolBE].connected && strlen(pi->connection_info[poolBE].database) > 0 && strlen(pi->connection_info[poolBE].user) > 0) + { + StrNCpy(processes[child].database, pi->connection_info[poolBE].database, POOLCONFIG_MAXIDENTLEN); + StrNCpy(processes[child].username, pi->connection_info[poolBE].user, POOLCONFIG_MAXIDENTLEN); + strftime(processes[child].create_time, POOLCONFIG_MAXDATELEN, "%Y-%m-%d %H:%M:%S", localtime(&pi->connection_info[poolBE].create_time)); + snprintf(processes[child].pool_counter, POOLCONFIG_MAXCOUNTLEN, "%d", pi->connection_info[poolBE].counter); + } + } + } *nrows = child; return processes; } -void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +processes_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { static short num_fields = 6; static char *field_names[] = {"pool_pid", "start_time", "database", "username", "create_time", "pool_counter"}; - short s; - int len; - int nrows; - int size; - int hsize; - int i; - static unsigned char nullmap[2] = {0xff, 0xff}; - int nbytes = (num_fields + 7)/8; + short s; + int len; + int nrows; + int size; + int hsize; + int i; + static unsigned char nullmap[2] = {0xff, 0xff}; + int nbytes = (num_fields + 7) / 8; - POOL_REPORT_PROCESSES *processes = get_processes(&nrows); + POOL_REPORT_PROCESSES *processes = get_processes(&nrows); send_row_description(frontend, backend, num_fields, field_names); if (MAJOR(backend) == PROTO_MAJOR_V2) { /* ascii row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { pool_write(frontend, "D", 1); pool_write_and_flush(frontend, nullmap, nbytes); size = strlen(processes[i].pool_pid); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, processes[i].pool_pid, size); size = strlen(processes[i].start_time); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, processes[i].start_time, size); size = strlen(processes[i].database); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, processes[i].database, size); size = strlen(processes[i].username); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, processes[i].username, size); size = strlen(processes[i].create_time); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, processes[i].create_time, size); size = strlen(processes[i].pool_counter); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, processes[i].pool_counter, size); } @@ -1665,16 +1692,16 @@ void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen else { /* data row */ - for (i=0;i<nrows;i++) + for (i = 0; i < nrows; i++) { pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - len += 4 + strlen(processes[i].pool_pid); /* int32 + data */ - len += 4 + strlen(processes[i].start_time); /* int32 + data */ - len += 4 + strlen(processes[i].database); /* int32 + data */ - len += 4 + strlen(processes[i].username); /* int32 + data */ - len += 4 + strlen(processes[i].create_time); /* int32 + data */ - len += 4 + strlen(processes[i].pool_counter); /* int32 + data */ + len = 6; /* int32 + int16; */ + len += 4 + strlen(processes[i].pool_pid); /* int32 + data */ + len += 4 + strlen(processes[i].start_time); /* int32 + data */ + len += 4 + strlen(processes[i].database); /* int32 + data */ + len += 4 + strlen(processes[i].username); /* int32 + data */ + len += 4 + strlen(processes[i].create_time); /* int32 + data */ + len += 4 + strlen(processes[i].pool_counter); /* int32 + data */ len = htonl(len); pool_write(frontend, &len, sizeof(len)); s = htons(num_fields); @@ -1711,7 +1738,8 @@ void processes_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backen pfree(processes); } -POOL_REPORT_VERSION* get_version(void) +POOL_REPORT_VERSION * +get_version(void) { POOL_REPORT_VERSION *version = palloc(sizeof(POOL_REPORT_VERSION)); @@ -1720,17 +1748,18 @@ POOL_REPORT_VERSION* get_version(void) return version; } -void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +version_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { static short num_fields = 1; static char *field_names[] = {"pool_version"}; - short s; - int len; - int size; - int hsize; + short s; + int len; + int size; + int hsize; static unsigned char nullmap[2] = {0xff, 0xff}; - int nbytes = (num_fields + 7)/8; + int nbytes = (num_fields + 7) / 8; POOL_REPORT_VERSION *version = get_version(); @@ -1743,7 +1772,7 @@ void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) pool_write_and_flush(frontend, nullmap, nbytes); size = strlen(version[0].version); - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, version[0].version, size); } @@ -1751,8 +1780,8 @@ void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) { /* data row */ pool_write(frontend, "D", 1); - len = 6; /* int32 + int16; */ - len += 4 + strlen(version[0].version); /* int32 + data */ + len = 6; /* int32 + int16; */ + len += 4 + strlen(version[0].version); /* int32 + data */ len = htonl(len); pool_write(frontend, &len, sizeof(len)); s = htons(num_fields); @@ -1763,7 +1792,7 @@ void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) pool_write(frontend, version[0].version, strlen(version[0].version)); } - send_complete_and_ready(frontend, backend, "SELECT",1); + send_complete_and_ready(frontend, backend, "SELECT", 1); pfree(version); } @@ -1771,81 +1800,83 @@ void version_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) /* * Show in memory cache reporting */ -void cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +void +cache_reporting(POOL_CONNECTION * frontend, POOL_CONNECTION_POOL * backend) { static char *field_names[] = {"num_cache_hits", "num_selects", "cache_hit_ratio", "num_hash_entries", "used_hash_entries", "num_cache_entries", "used_cache_entries_size", "free_cache_entries_size", "fragment_cache_entries_size"}; - short num_fields = sizeof(field_names)/sizeof(char *); - int i; - short s; - int len; - int size; - int hsize; + short num_fields = sizeof(field_names) / sizeof(char *); + int i; + short s; + int len; + int size; + int hsize; static unsigned char nullmap[2] = {0xff, 0xff}; - int nbytes = (num_fields + 7)/8; - volatile POOL_SHMEM_STATS *mystats; + int nbytes = (num_fields + 7) / 8; + volatile POOL_SHMEM_STATS *mystats; pool_sigset_t oldmask; - double ratio; + double ratio; #define POOL_CACHE_STATS_MAX_STRING_LEN 32 - typedef struct { - int len; /* length of string excluding null terminate */ - char string[POOL_CACHE_STATS_MAX_STRING_LEN+1]; - } MY_STRING_CACHE_STATS; + typedef struct + { + int len; /* length of string excluding null terminate */ + char string[POOL_CACHE_STATS_MAX_STRING_LEN + 1]; + } MY_STRING_CACHE_STATS; MY_STRING_CACHE_STATS *strp; - strp = palloc(num_fields*sizeof(MY_STRING_CACHE_STATS)); + strp = palloc(num_fields * sizeof(MY_STRING_CACHE_STATS)); /* * Get raw cache stat data */ - POOL_SETMASK2(&BlockSig, &oldmask); - pool_shmem_lock(); - - PG_TRY(); - { - mystats = pool_get_shmem_storage_stats(); - } - PG_CATCH(); - { - pool_shmem_unlock(); - POOL_SETMASK(&oldmask); - PG_RE_THROW(); - } - PG_END_TRY(); - pool_shmem_unlock(); - POOL_SETMASK(&oldmask); + POOL_SETMASK2(&BlockSig, &oldmask); + pool_shmem_lock(); + + PG_TRY(); + { + mystats = pool_get_shmem_storage_stats(); + } + PG_CATCH(); + { + pool_shmem_unlock(); + POOL_SETMASK(&oldmask); + PG_RE_THROW(); + } + PG_END_TRY(); + pool_shmem_unlock(); + POOL_SETMASK(&oldmask); /* * Convert to string */ i = 0; - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%lld", mystats->cache_stats.num_cache_hits); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%lld", mystats->cache_stats.num_selects); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%lld", mystats->cache_stats.num_cache_hits); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%lld", mystats->cache_stats.num_selects); if ((mystats->cache_stats.num_cache_hits + mystats->cache_stats.num_selects) == 0) { ratio = 0.0; } else { - ratio = (double)mystats->cache_stats.num_cache_hits/(mystats->cache_stats.num_selects + mystats->cache_stats.num_cache_hits); + ratio = (double) mystats->cache_stats.num_cache_hits / (mystats->cache_stats.num_selects + mystats->cache_stats.num_cache_hits); } - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%.2f", ratio); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%d", mystats->num_hash_entries); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%d", mystats->used_hash_entries); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%d", mystats->num_cache_entries); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%ld", mystats->used_cache_entries_size); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%ld", mystats->free_cache_entries_size); - snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN+1, "%ld", mystats->fragment_cache_entries_size); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%.2f", ratio); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%d", mystats->num_hash_entries); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%d", mystats->used_hash_entries); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%d", mystats->num_cache_entries); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%ld", mystats->used_cache_entries_size); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%ld", mystats->free_cache_entries_size); + snprintf(strp[i++].string, POOL_CACHE_STATS_MAX_STRING_LEN + 1, "%ld", mystats->fragment_cache_entries_size); /* * Calculate total data length */ - len = 2; /* number of fields (int16) */ - for (i=0;i<num_fields;i++) + len = 2; /* number of fields (int16) */ + for (i = 0; i < num_fields; i++) { strp[i].len = strlen(strp[i].string); - len += 4 /* length of string (int32) */ + len += 4 /* length of string (int32) */ + strp[i].len; } @@ -1858,10 +1889,10 @@ void cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) pool_write(frontend, "D", 1); pool_write(frontend, nullmap, nbytes); - for (i=0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { size = strp[i].len + 1; - hsize = htonl(size+4); + hsize = htonl(size + 4); pool_write(frontend, &hsize, sizeof(hsize)); pool_write(frontend, strp[i].string, size); } @@ -1871,13 +1902,13 @@ void cache_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) /* Kind */ pool_write(frontend, "D", 1); /* Packet length */ - len = htonl(len+sizeof(int32)); + len = htonl(len + sizeof(int32)); pool_write(frontend, &len, sizeof(len)); /* Number of fields */ s = htons(num_fields); pool_write(frontend, &s, sizeof(s)); - for (i=0;i<num_fields;i++) + for (i = 0; i < num_fields; i++) { hsize = htonl(strp[i].len); pool_write(frontend, &hsize, sizeof(hsize)); diff --git a/src/utils/pool_relcache.c b/src/utils/pool_relcache.c index cb2ff5182..7d857f0dc 100644 --- a/src/utils/pool_relcache.c +++ b/src/utils/pool_relcache.c @@ -34,12 +34,14 @@ #include "utils/elog.h" static void SearchRelCacheErrorCb(void *arg); + /* * Create relation cache */ -POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, - func_ptr register_func, func_ptr unregister_func, - bool issessionlocal) +POOL_RELCACHE * +pool_create_relcache(int cachesize, char *sql, + func_ptr register_func, func_ptr unregister_func, + bool issessionlocal) { POOL_RELCACHE *p; PoolRelCache *ip; @@ -51,14 +53,15 @@ POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, (errmsg("failed to create relcache: wrong cache size: %d", cachesize))); return NULL; } + /* * Create the relcache in session context if the cache is session local, * otherwise make home in TopMemoryContext */ old_context = MemoryContextSwitchTo(TopMemoryContext); - ip = (PoolRelCache *)palloc0(sizeof(PoolRelCache)*cachesize); - p = (POOL_RELCACHE *)palloc(sizeof(POOL_RELCACHE)); + ip = (PoolRelCache *) palloc0(sizeof(PoolRelCache) * cachesize); + p = (POOL_RELCACHE *) palloc(sizeof(POOL_RELCACHE)); MemoryContextSwitchTo(old_context); @@ -69,19 +72,21 @@ POOL_RELCACHE *pool_create_relcache(int cachesize, char *sql, p->cache_is_session_local = issessionlocal; p->no_cache_if_zero = false; p->cache = ip; - + return p; } + /* * Discard relation cache. */ -void pool_discard_relcache(POOL_RELCACHE *relcache) +void +pool_discard_relcache(POOL_RELCACHE * relcache) { - int i; + int i; - for (i=0;i<relcache->num;i++) + for (i = 0; i < relcache->num; i++) { - (*relcache->unregister_func)(relcache->cache[i].data); + (*relcache->unregister_func) (relcache->cache[i].data); } pfree(relcache->cache); pfree(relcache); @@ -91,17 +96,18 @@ void pool_discard_relcache(POOL_RELCACHE *relcache) * Search relcache. If found, return user data. Otherwise return 0. * If not found in cache, do the query and store the result into cache and return it. */ -void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backend, char *table) +void * +pool_search_relcache(POOL_RELCACHE * relcache, POOL_CONNECTION_POOL * backend, char *table) { - char *dbname; - int i; - int maxrefcnt = INT_MAX; - char query[1024]; + char *dbname; + int i; + int maxrefcnt = INT_MAX; + char query[1024]; POOL_SELECT_RESULT *res = NULL; - int index = 0; - int local_session_id; - time_t now; - void *result; + int index = 0; + int local_session_id; + time_t now; + void *result; ErrorContextCallback callback; local_session_id = pool_get_local_session_id(); @@ -114,7 +120,7 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen now = time(NULL); /* Look for cache first */ - for (i=0;i<relcache->num;i++) + for (i = 0; i < relcache->num; i++) { /* * If cache is session local, we need to check session id @@ -133,7 +139,7 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen if (now > relcache->cache[i].expire) { ereport(DEBUG1, - (errmsg("searching relcache"), + (errmsg("searching relcache"), errdetail("relcache for database:%s table:%s expired. now:%ld expiration time:%ld", dbname, table, now, relcache->cache[i].expire))); relcache->cache[i].refcnt = 0; @@ -169,7 +175,7 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen /* * Look for replacement in cache */ - for (i=0;i<relcache->num;i++) + for (i = 0; i < relcache->num; i++) { /* * If cache is session local, we can discard old cache immediately @@ -200,12 +206,12 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen if (relcache->cache[index].refcnt != 0) { ereport(LOG, - (errmsg("searching relcache. cache replacement occured"))); + (errmsg("searching relcache. cache replacement occured"))); } /* Register cache */ - result = (*relcache->register_func)(res); + result = (*relcache->register_func) (res); if (!pool_is_ignore_till_sync() && (!relcache->no_cache_if_zero || result)) { @@ -221,36 +227,39 @@ void *pool_search_relcache(POOL_RELCACHE *relcache, POOL_CONNECTION_POOL *backen { relcache->cache[index].expire = 0; } + /* * Call user defined unregister/register function. */ - (*relcache->unregister_func)(relcache->cache[index].data); + (*relcache->unregister_func) (relcache->cache[index].data); relcache->cache[index].data = result; } free_select_result(res); - return result; + return result; } -static void SearchRelCacheErrorCb(void *arg) +static void +SearchRelCacheErrorCb(void *arg) { errcontext("while searching system catalog, When relcache is missed"); } -char *remove_quotes_and_schema_from_relname(char *table) +char * +remove_quotes_and_schema_from_relname(char *table) { static char rel[MAX_ITEM_LENGTH]; - char *p; - int i = 0; + char *p; + int i = 0; /* get rid of schema name */ p = strchr(table, '.'); if (p) - table = p+1; + table = p + 1; /* get rid of quotation marks */ - for (i=0; *table; table++) + for (i = 0; *table; table++) { if (*table != '"') rel[i++] = *table; @@ -264,27 +273,31 @@ char *remove_quotes_and_schema_from_relname(char *table) * Standard register/unregister function for "SELECT count(*)" type * query. Returns row count. */ -void *int_register_func(POOL_SELECT_RESULT *res) +void * +int_register_func(POOL_SELECT_RESULT * res) { if (res->numrows >= 1) - return (void *)atol(res->data[0]); - return (void *)0; + return (void *) atol(res->data[0]); + return (void *) 0; } -void *int_unregister_func(void *data) +void * +int_unregister_func(void *data) { /* Nothing to do since no memory was allocated */ return NULL; } -void *string_register_func(POOL_SELECT_RESULT *res) +void * +string_register_func(POOL_SELECT_RESULT * res) { - return (res->numrows > 0) ? strdup(res->data[0]): NULL; + return (res->numrows > 0) ? strdup(res->data[0]) : NULL; } -void *string_unregister_func(void *data) +void * +string_unregister_func(void *data) { - if(data) + if (data) free(data); - return (void *)0; + return (void *) 0; } diff --git a/src/utils/pool_select_walker.c b/src/utils/pool_select_walker.c index bc3dac573..3970d8518 100644 --- a/src/utils/pool_select_walker.c +++ b/src/utils/pool_select_walker.c @@ -37,7 +37,7 @@ static bool temp_table_walker(Node *node, void *context); static bool unlogged_table_walker(Node *node, void *context); static bool view_walker(Node *node, void *context); static bool is_temp_table(char *table_name); -static bool insertinto_or_locking_clause_walker(Node *node, void *context); +static bool insertinto_or_locking_clause_walker(Node *node, void *context); static bool is_immutable_function(char *fname); static bool select_table_walker(Node *node, void *context); static bool non_immutable_function_call_walker(Node *node, void *context); @@ -48,9 +48,10 @@ static char *strip_quote(char *str); * modify database. We check black/white function list to determine * whether the function modifies database. */ -bool pool_has_function_call(Node *node) +bool +pool_has_function_call(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -66,9 +67,10 @@ bool pool_has_function_call(Node *node) /* * Search the pg_terminate_backend() call in the query */ -int pool_get_terminate_backend_pid(Node *node) +int +pool_get_terminate_backend_pid(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -85,10 +87,11 @@ int pool_get_terminate_backend_pid(Node *node) /* * Return true if this SELECT has system catalog table. */ -bool pool_has_system_catalog(Node *node) +bool +pool_has_system_catalog(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -103,10 +106,11 @@ bool pool_has_system_catalog(Node *node) /* * Return true if this SELECT has temporary table. */ -bool pool_has_temp_table(Node *node) +bool +pool_has_temp_table(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -121,10 +125,11 @@ bool pool_has_temp_table(Node *node) /* * Return true if this SELECT has unlogged table. */ -bool pool_has_unlogged_table(Node *node) +bool +pool_has_unlogged_table(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -139,10 +144,11 @@ bool pool_has_unlogged_table(Node *node) /* * Return true if this SELECT has a view. */ -bool pool_has_view(Node *node) +bool +pool_has_view(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -157,9 +163,10 @@ bool pool_has_view(Node *node) /* * Return true if this SELECT has INSERT INTO or FOR SHARE or FOR UPDATE. */ -bool pool_has_insertinto_or_locking_clause(Node *node) +bool +pool_has_insertinto_or_locking_clause(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; @@ -169,8 +176,8 @@ bool pool_has_insertinto_or_locking_clause(Node *node) raw_expression_tree_walker(node, insertinto_or_locking_clause_walker, &ctx); ereport(DEBUG1, - (errmsg("checking if query has INSERT INTO, FOR SHARE or FOR UPDATE"), - errdetail("result = %d",ctx.has_insertinto_or_locking_clause))); + (errmsg("checking if query has INSERT INTO, FOR SHARE or FOR UPDATE"), + errdetail("result = %d", ctx.has_insertinto_or_locking_clause))); return ctx.has_insertinto_or_locking_clause; } @@ -180,76 +187,82 @@ bool pool_has_insertinto_or_locking_clause(Node *node) * Return 1 on success (found in list) * Return 0 when not found in list * Return -1 if the given search type doesn't exist. - * Search type supported are: WHITELIST and BLACKLIST + * Search type supported are: WHITELIST and BLACKLIST */ -int pattern_compare(char *str, const int type, const char *param_name) +int +pattern_compare(char *str, const int type, const char *param_name) { - int i = 0; - char *s; - int result = 0; + int i = 0; + char *s; + int result = 0; RegPattern *lists_patterns; - int *pattc; + int *pattc; if (strcmp(param_name, "white_function_list") == 0 || - strcmp(param_name, "black_function_list") == 0) + strcmp(param_name, "black_function_list") == 0) { lists_patterns = pool_config->lists_patterns; pattc = &pool_config->pattc; - } else if (strcmp(param_name, "white_memqcache_table_list") == 0 || - strcmp(param_name, "black_memqcache_table_list") == 0) + } + else if (strcmp(param_name, "white_memqcache_table_list") == 0 || + strcmp(param_name, "black_memqcache_table_list") == 0) { lists_patterns = pool_config->lists_memqcache_table_patterns; pattc = &pool_config->memqcache_table_pattc; - } + } else if (strcmp(param_name, "black_query_pattern_list") == 0) { lists_patterns = pool_config->lists_query_patterns; pattc = &pool_config->query_pattc; - } else { + } + else + { ereport(WARNING, (errmsg("pattern_compare: unknown paramname %s", param_name))); return -1; } s = strip_quote(str); - for (i = 0; i < *pattc; i++) { + for (i = 0; i < *pattc; i++) + { if (lists_patterns[i].type != type) continue; if (regexec(&lists_patterns[i].regexv, s, 0, 0, 0) == 0) { - switch(type) { - /* return 1 if string matches whitelist pattern */ - case WHITELIST: - ereport(DEBUG2, - (errmsg("comparing function name in whitelist regex array"), - errdetail("pattern_compare: %s (%s) matched: %s", - param_name, lists_patterns[i].pattern, s))); - result = 1; - break; - /* return 1 if string matches blacklist pattern */ - case BLACKLIST: - ereport(DEBUG2, - (errmsg("comparing function name in blacklist regex array"), - errdetail("pattern_compare: %s (%s) matched: %s", - param_name, lists_patterns[i].pattern, s))); - result = 1; - break; - default: - ereport(WARNING, - (errmsg("pattern_compare: \"%s\" unknown pattern match type: \"%s\"", param_name, s))); - result = -1; - break; + switch (type) + { + /* return 1 if string matches whitelist pattern */ + case WHITELIST: + ereport(DEBUG2, + (errmsg("comparing function name in whitelist regex array"), + errdetail("pattern_compare: %s (%s) matched: %s", + param_name, lists_patterns[i].pattern, s))); + result = 1; + break; + /* return 1 if string matches blacklist pattern */ + case BLACKLIST: + ereport(DEBUG2, + (errmsg("comparing function name in blacklist regex array"), + errdetail("pattern_compare: %s (%s) matched: %s", + param_name, lists_patterns[i].pattern, s))); + result = 1; + break; + default: + ereport(WARNING, + (errmsg("pattern_compare: \"%s\" unknown pattern match type: \"%s\"", param_name, s))); + result = -1; + break; } /* return the result */ break; } ereport(DEBUG2, - (errmsg("comparing function name in blacklist/whitelist regex array"), + (errmsg("comparing function name in blacklist/whitelist regex array"), errdetail("pattern_compare: %s (%s) not matched: %s", param_name, lists_patterns[i].pattern, s))); } @@ -258,14 +271,16 @@ int pattern_compare(char *str, const int type, const char *param_name) return result; } -static char *strip_quote(char *str) +static char * +strip_quote(char *str) { - char *after; - int i = 0; + char *after; + int i = 0; after = malloc(sizeof(char) * strlen(str) + 1); - do { + do + { if (*str != '"') { after[i] = *str; @@ -283,18 +298,19 @@ static char *strip_quote(char *str) * Walker function to find a function call which is supposed to write * database. */ -static bool function_call_walker(Node *node, void *context) +static bool +function_call_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; + SelectContext *ctx = (SelectContext *) context; if (node == NULL) return false; if (IsA(node, FuncCall)) { - FuncCall *fcall = (FuncCall *)node; - char *fname; - int length = list_length(fcall->funcname); + FuncCall *fcall = (FuncCall *) node; + char *fname; + int length = list_length(fcall->funcname); if (length > 0) { @@ -304,39 +320,47 @@ static bool function_call_walker(Node *node, void *context) } else { - fname = strVal(lsecond(fcall->funcname)); /* with schema qualification */ + fname = strVal(lsecond(fcall->funcname)); /* with schema + * qualification */ } ereport(DEBUG1, - (errmsg("function call walker, function name: \"%s\"", fname))); + (errmsg("function call walker, function name: \"%s\"", fname))); if (ctx->pg_terminate_backend_pid == 0 && strcmp("pg_terminate_backend", fname) == 0) { if (list_length(fcall->args) == 1) { - Node *arg = linitial(fcall->args); + Node *arg = linitial(fcall->args); + if (IsA(arg, A_Const) && - ((A_Const *)arg)->val.type == T_Integer) + ((A_Const *) arg)->val.type == T_Integer) { - ctx->pg_terminate_backend_pid = ((A_Const *)arg)->val.val.ival; + ctx->pg_terminate_backend_pid = ((A_Const *) arg)->val.val.ival; ereport(DEBUG1, - (errmsg("pg_terminate_backend pid = %d",ctx->pg_terminate_backend_pid))); + (errmsg("pg_terminate_backend pid = %d", ctx->pg_terminate_backend_pid))); } } } + /* * Check white list if any. */ if (pool_config->num_white_function_list > 0) { /* Search function in the white list regex patterns */ - if (pattern_compare(fname, WHITELIST, "white_function_list") == 1) { - /* If the function is found in the white list, we can ignore it */ + if (pattern_compare(fname, WHITELIST, "white_function_list") == 1) + { + /* + * If the function is found in the white list, we can + * ignore it + */ return raw_expression_tree_walker(node, function_call_walker, context); } + /* - * Since the function was not found in white list, we - * have found a writing function. + * Since the function was not found in white list, we have + * found a writing function. */ ctx->has_function_call = true; return false; @@ -348,7 +372,8 @@ static bool function_call_walker(Node *node, void *context) if (pool_config->num_black_function_list > 0) { /* Search function in the black list regex patterns */ - if (pattern_compare(fname, BLACKLIST, "black_function_list") == 1) { + if (pattern_compare(fname, BLACKLIST, "black_function_list") == 1) + { /* Found. */ ctx->has_function_call = true; return false; @@ -365,17 +390,17 @@ static bool function_call_walker(Node *node, void *context) static bool system_catalog_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; + SelectContext *ctx = (SelectContext *) context; if (node == NULL) return false; if (IsA(node, RangeVar)) { - RangeVar *rgv = (RangeVar *)node; + RangeVar *rgv = (RangeVar *) node; ereport(DEBUG1, - (errmsg("system catalog walker, checking relation \"%s\"",rgv->relname))); + (errmsg("system catalog walker, checking relation \"%s\"", rgv->relname))); if (is_system_catalog(rgv->relname)) { @@ -392,17 +417,17 @@ system_catalog_walker(Node *node, void *context) static bool temp_table_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; + SelectContext *ctx = (SelectContext *) context; if (node == NULL) return false; if (IsA(node, RangeVar)) { - RangeVar *rgv = (RangeVar *)node; + RangeVar *rgv = (RangeVar *) node; ereport(DEBUG1, - (errmsg("temporary table walker. checking relation \"%s\"",rgv->relname))); + (errmsg("temporary table walker. checking relation \"%s\"", rgv->relname))); if (is_temp_table(rgv->relname)) { @@ -419,19 +444,20 @@ temp_table_walker(Node *node, void *context) static bool unlogged_table_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; - char *relname; + SelectContext *ctx = (SelectContext *) context; + char *relname; if (node == NULL) return false; if (IsA(node, RangeVar)) { - RangeVar *rgv = (RangeVar *)node; + RangeVar *rgv = (RangeVar *) node; + relname = make_table_name_from_rangevar(rgv); - + ereport(DEBUG1, - (errmsg("unlogged table walker. checking relation \"%s\"",relname))); + (errmsg("unlogged table walker. checking relation \"%s\"", relname))); if (is_unlogged_table(relname)) { @@ -448,19 +474,20 @@ unlogged_table_walker(Node *node, void *context) static bool view_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; - char *relname; + SelectContext *ctx = (SelectContext *) context; + char *relname; if (node == NULL) return false; if (IsA(node, RangeVar)) { - RangeVar *rgv = (RangeVar *)node; + RangeVar *rgv = (RangeVar *) node; + relname = make_table_name_from_rangevar(rgv); ereport(DEBUG1, - (errmsg("view walker. checking relation \"%s\"",relname))); + (errmsg("view walker. checking relation \"%s\"", relname))); if (is_view(relname)) { @@ -475,7 +502,8 @@ view_walker(Node *node, void *context) * Judge the table used in a query represented by node is a system * catalog or not. */ -static bool is_system_catalog(char *table_name) +static bool +is_system_catalog(char *table_name) { /* * Query to know if pg_namespace exists. PostgreSQL 7.2 or before doesn't have. @@ -491,10 +519,10 @@ static bool is_system_catalog(char *table_name) #define ISBELONGTOPGCATALOGQUERY3 "SELECT count(*) FROM pg_class AS c, pg_namespace AS n WHERE c.oid = pg_catalog.to_regclass('\"%s\"') AND c.relnamespace = n.oid AND n.nspname = 'pg_catalog'" - int hasreliscatalog; - bool result; - static POOL_RELCACHE *hasreliscatalog_cache; - static POOL_RELCACHE *relcache; + int hasreliscatalog; + bool result; + static POOL_RELCACHE * hasreliscatalog_cache; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; if (table_name == NULL) @@ -512,13 +540,13 @@ static bool is_system_catalog(char *table_name) */ if (!hasreliscatalog_cache) { - char *query; + char *query; query = HASPGNAMESPACEQUERY; hasreliscatalog_cache = pool_create_relcache(pool_config->relcache_size, query, - int_register_func, int_unregister_func, - false); + int_register_func, int_unregister_func, + false); if (hasreliscatalog_cache == NULL) { ereport(WARNING, @@ -527,7 +555,7 @@ static bool is_system_catalog(char *table_name) } } - hasreliscatalog = pool_search_relcache(hasreliscatalog_cache, backend, "pg_namespace")==0?0:1; + hasreliscatalog = pool_search_relcache(hasreliscatalog_cache, backend, "pg_namespace") == 0 ? 0 : 1; if (hasreliscatalog) { @@ -536,7 +564,7 @@ static bool is_system_catalog(char *table_name) */ if (!relcache) { - char *query; + char *query; /* PostgreSQL 9.4 or later has to_regclass() */ if (pool_has_to_regclass()) @@ -563,10 +591,11 @@ static bool is_system_catalog(char *table_name) return false; } } + /* * Search relcache. */ - result = pool_search_relcache(relcache, backend, table_name)==0?false:true; + result = pool_search_relcache(relcache, backend, table_name) == 0 ? false : true; return result; } @@ -580,9 +609,10 @@ static bool is_system_catalog(char *table_name) * Judge the table used in a query represented by node is a temporary * table or not. */ -static POOL_RELCACHE *is_temp_table_relcache; +static POOL_RELCACHE * is_temp_table_relcache; -static bool is_temp_table(char *table_name) +static bool +is_temp_table(char *table_name) { /* * Query to know if pg_class has relistemp column or not. @@ -606,15 +636,15 @@ static bool is_temp_table(char *table_name) */ #define ISTEMPQUERY84 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.relname = '%s' AND c.relistemp" - int hasrelistemp; - bool result; - static POOL_RELCACHE *hasrelistemp_cache; - char *query; + int hasrelistemp; + bool result; + static POOL_RELCACHE * hasrelistemp_cache; + char *query; POOL_CONNECTION_POOL *backend; if (table_name == NULL) { - return false; + return false; } backend = pool_get_session_context(false)->backend; @@ -625,8 +655,8 @@ static bool is_temp_table(char *table_name) if (!hasrelistemp_cache) { hasrelistemp_cache = pool_create_relcache(pool_config->relcache_size, HASRELITEMPPQUERY, - int_register_func, int_unregister_func, - false); + int_register_func, int_unregister_func, + false); if (hasrelistemp_cache == NULL) { ereport(WARNING, @@ -635,7 +665,7 @@ static bool is_temp_table(char *table_name) } } - hasrelistemp = pool_search_relcache(hasrelistemp_cache, backend, "pg_class")==0?0:1; + hasrelistemp = pool_search_relcache(hasrelistemp_cache, backend, "pg_class") == 0 ? 0 : 1; if (hasrelistemp) query = ISTEMPQUERY84; else @@ -660,14 +690,15 @@ static bool is_temp_table(char *table_name) /* * Search relcache. */ - result = pool_search_relcache(is_temp_table_relcache, backend, table_name)==0?false:true; + result = pool_search_relcache(is_temp_table_relcache, backend, table_name) == 0 ? false : true; return result; } /* * Discard relcache used by is_temp_table_relcache(). */ -void discard_temp_table_relcache(void) +void +discard_temp_table_relcache(void) { if (is_temp_table_relcache) { @@ -680,7 +711,8 @@ void discard_temp_table_relcache(void) * Judge the table used in a query represented by node is a unlogged * table or not. */ -bool is_unlogged_table(char *table_name) +bool +is_unlogged_table(char *table_name) { /* * Query to know if pg_class has relpersistence column or not. @@ -698,9 +730,9 @@ bool is_unlogged_table(char *table_name) #define ISUNLOGGEDQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pg_catalog.to_regclass('%s') AND c.relpersistence = 'u'" - int hasrelpersistence; - static POOL_RELCACHE *hasrelpersistence_cache; - static POOL_RELCACHE *relcache; + int hasrelpersistence; + static POOL_RELCACHE * hasrelpersistence_cache; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; if (table_name == NULL) @@ -729,11 +761,11 @@ bool is_unlogged_table(char *table_name) } } - hasrelpersistence = pool_search_relcache(hasrelpersistence_cache, backend, "pg_class")==0?0:1; + hasrelpersistence = pool_search_relcache(hasrelpersistence_cache, backend, "pg_class") == 0 ? 0 : 1; if (hasrelpersistence) { - bool result; - char *query; + bool result; + char *query; /* PostgreSQL 9.4 or later has to_regclass() */ if (pool_has_to_regclass()) @@ -769,7 +801,7 @@ bool is_unlogged_table(char *table_name) /* * Search relcache. */ - result = pool_search_relcache(relcache, backend, table_name)==0?false:true; + result = pool_search_relcache(relcache, backend, table_name) == 0 ? false : true; return result; } else @@ -781,7 +813,8 @@ bool is_unlogged_table(char *table_name) /* * Judge the table used in a query is a view or not. */ -bool is_view(char *table_name) +bool +is_view(char *table_name) { /* * Query to know if the target table is a view (including a materialized view). @@ -792,10 +825,10 @@ bool is_view(char *table_name) #define ISVIEWQUERY3 "SELECT count(*) FROM pg_catalog.pg_class AS c WHERE c.oid = pg_catalog.to_regclass('%s') AND (c.relkind = 'v' OR c.relkind = 'm')" - static POOL_RELCACHE *relcache; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; - bool result; - char *query; + bool result; + char *query; if (table_name == NULL) { @@ -839,24 +872,25 @@ bool is_view(char *table_name) /* * Search relcache. */ - result = pool_search_relcache(relcache, backend, table_name)==0?false:true; + result = pool_search_relcache(relcache, backend, table_name) == 0 ? false : true; return result; } /* * Judge if we have pgpool_regclass or not. */ -bool pool_has_pgpool_regclass(void) +bool +pool_has_pgpool_regclass(void) { /* * Query to know if pgpool_regclass exists. */ #define HASPGPOOL_REGCLASSQUERY "SELECT count(*) from (SELECT has_function_privilege('%s', 'pgpool_regclass(cstring)', 'execute') WHERE EXISTS(SELECT * FROM pg_catalog.pg_proc AS p WHERE p.proname = 'pgpool_regclass')) AS s" - bool result; - static POOL_RELCACHE *relcache; + bool result; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; - char *user; + char *user; backend = pool_get_session_context(false)->backend; user = MASTER_CONNECTION(backend)->sp->user; @@ -874,24 +908,25 @@ bool pool_has_pgpool_regclass(void) } } - result = pool_search_relcache(relcache, backend, user)==0?0:1; + result = pool_search_relcache(relcache, backend, user) == 0 ? 0 : 1; return result; } /* * Judge if we have to_regclass or not. */ -bool pool_has_to_regclass(void) +bool +pool_has_to_regclass(void) { /* * Query to know if to_regclass exists. */ #define HAS_TOREGCLASSQUERY "SELECT count(*) from (SELECT has_function_privilege('%s', 'pg_catalog.to_regclass(cstring)', 'execute') WHERE EXISTS(SELECT * FROM pg_catalog.pg_proc AS p WHERE p.proname = 'to_regclass')) AS s" - bool result; - static POOL_RELCACHE *relcache; + bool result; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; - char *user; + char *user; backend = pool_get_session_context(false)->backend; user = MASTER_CONNECTION(backend)->sp->user; @@ -909,21 +944,22 @@ bool pool_has_to_regclass(void) } } - result = pool_search_relcache(relcache, backend, user)==0?0:1; + result = pool_search_relcache(relcache, backend, user) == 0 ? 0 : 1; return result; } /* * Walker function to find intoClause or lockingClause. */ -static bool insertinto_or_locking_clause_walker(Node *node, void *context) +static bool +insertinto_or_locking_clause_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; + SelectContext *ctx = (SelectContext *) context; if (node == NULL) return false; - if (IsA(node, IntoClause) || IsA(node, LockingClause)) + if (IsA(node, IntoClause) ||IsA(node, LockingClause)) { ctx->has_insertinto_or_locking_clause = true; return false; @@ -934,19 +970,20 @@ static bool insertinto_or_locking_clause_walker(Node *node, void *context) /* * Return true if this SELECT has non immutable function calls. */ -bool pool_has_non_immutable_function_call(Node *node) +bool +pool_has_non_immutable_function_call(Node *node) { - SelectContext ctx; + SelectContext ctx; if (!IsA(node, SelectStmt)) return false; - ctx.has_non_immutable_function_call = false; + ctx.has_non_immutable_function_call = false; raw_expression_tree_walker(node, non_immutable_function_call_walker, &ctx); ereport(DEBUG1, - (errmsg("checking if SELECT statement contains the IMMUTABLE function call"), + (errmsg("checking if SELECT statement contains the IMMUTABLE function call"), errdetail("result = %d", ctx.has_non_immutable_function_call))); return ctx.has_non_immutable_function_call; @@ -955,18 +992,19 @@ bool pool_has_non_immutable_function_call(Node *node) /* * Walker function to find non immutable function call. */ -static bool non_immutable_function_call_walker(Node *node, void *context) +static bool +non_immutable_function_call_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; + SelectContext *ctx = (SelectContext *) context; if (node == NULL) return false; if (IsA(node, FuncCall)) { - FuncCall *fcall = (FuncCall *)node; - char *fname; - int length = list_length(fcall->funcname); + FuncCall *fcall = (FuncCall *) node; + char *fname; + int length = list_length(fcall->funcname); if (length > 0) { @@ -976,11 +1014,12 @@ static bool non_immutable_function_call_walker(Node *node, void *context) } else { - fname = strVal(lsecond(fcall->funcname)); /* with schema qualification */ + fname = strVal(lsecond(fcall->funcname)); /* with schema + * qualification */ } ereport(DEBUG1, - (errmsg("non immutable function walker. checking function \"%s\"",fname))); + (errmsg("non immutable function walker. checking function \"%s\"", fname))); /* Check system catalog if the function is immutable */ if (is_immutable_function(fname) == false) @@ -993,8 +1032,8 @@ static bool non_immutable_function_call_walker(Node *node, void *context) } else if (IsA(node, TypeCast)) { - /* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc.*/ - TypeCast *tc = (TypeCast *) node; + /* CURRENT_DATE, CURRENT_TIME, LOCALTIMESTAMP, LOCALTIME etc. */ + TypeCast *tc = (TypeCast *) node; if ((isSystemType((Node *) tc->typeName, "date") || isSystemType((Node *) tc->typeName, "timestamp") || @@ -1013,14 +1052,15 @@ static bool non_immutable_function_call_walker(Node *node, void *context) /* * Check if the function is stable. */ -static bool is_immutable_function(char *fname) +static bool +is_immutable_function(char *fname) { /* * Query to know if the function is IMMUTABLE */ #define IS_STABLE_FUNCTION_QUERY "SELECT count(*) FROM pg_catalog.pg_proc AS p WHERE p.proname = '%s' AND p.provolatile = 'i'" - bool result; - static POOL_RELCACHE *relcache; + bool result; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; backend = pool_get_session_context(false)->backend; @@ -1037,14 +1077,14 @@ static bool is_immutable_function(char *fname) return false; } ereport(DEBUG1, - (errmsg("checking if the function is IMMUTABLE"), + (errmsg("checking if the function is IMMUTABLE"), errdetail("relcache created"))); } - result = (pool_search_relcache(relcache, backend, fname)==0) ? 0 : 1; + result = (pool_search_relcache(relcache, backend, fname) == 0) ? 0 : 1; ereport(DEBUG1, - (errmsg("checking if the function is IMMUTABLE"), + (errmsg("checking if the function is IMMUTABLE"), errdetail("search result = %d", result))); return result; } @@ -1052,7 +1092,8 @@ static bool is_immutable_function(char *fname) /* * Convert table_name(possibly including schema name) to oid */ -int pool_table_name_to_oid(char *table_name) +int +pool_table_name_to_oid(char *table_name) { /* * Query to convert table name to oid @@ -1061,10 +1102,10 @@ int pool_table_name_to_oid(char *table_name) #define TABLE_TO_OID_QUERY2 "SELECT oid FROM pg_class WHERE relname = '%s'" #define TABLE_TO_OID_QUERY3 "SELECT COALESCE(pg_catalog.to_regclass('%s')::oid, 0)" - int oid = 0; - static POOL_RELCACHE *relcache; + int oid = 0; + static POOL_RELCACHE * relcache; POOL_CONNECTION_POOL *backend; - char *query; + char *query; if (table_name == NULL) { @@ -1104,17 +1145,18 @@ int pool_table_name_to_oid(char *table_name) return oid; } - /* Se do not cache if pgpool_regclass() returns 0, which indicates + /* + * Se do not cache if pgpool_regclass() returns 0, which indicates * there's no such a table. In this case we do not want to cache the * state because the table might be created later in this session. */ - relcache->no_cache_if_zero = true; + relcache->no_cache_if_zero = true; } /* * Search relcache. */ - oid = (int)(intptr_t)pool_search_relcache(relcache, backend, table_name); + oid = (int) (intptr_t) pool_search_relcache(relcache, backend, table_name); return oid; } @@ -1123,9 +1165,10 @@ int pool_table_name_to_oid(char *table_name) * Oids are returned as an int array. The contents of oid array are * discarded by next call to this function. */ -int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext *ctx) +int +pool_extract_table_oids_from_select_stmt(Node *node, SelectContext * ctx) { - if(!node) + if (!node) return 0; if (!IsA(node, SelectStmt)) return 0; @@ -1142,17 +1185,17 @@ int pool_extract_table_oids_from_select_stmt(Node *node, SelectContext *ctx) static bool select_table_walker(Node *node, void *context) { - SelectContext *ctx = (SelectContext *) context; - int num_oids; + SelectContext *ctx = (SelectContext *) context; + int num_oids; if (node == NULL) return false; if (IsA(node, RangeVar)) { - RangeVar *rgv = (RangeVar *)node; - char *table; - int oid; + RangeVar *rgv = (RangeVar *) node; + char *table; + int oid; table = make_table_name_from_rangevar(rgv); oid = pool_table_name_to_oid(table); @@ -1162,7 +1205,7 @@ select_table_walker(Node *node, void *context) if (POOL_MAX_SELECT_OIDS <= ctx->num_oids) { ereport(DEBUG1, - (errmsg("extracting table oids from SELECT statement"), + (errmsg("extracting table oids from SELECT statement"), errdetail("number of oids = %d exceeds the maximum limit = %d", ctx->num_oids, POOL_MAX_SELECT_OIDS))); return false; @@ -1174,7 +1217,7 @@ select_table_walker(Node *node, void *context) strlcpy(ctx->table_names[num_oids], table, POOL_NAMEDATALEN); ereport(DEBUG1, - (errmsg("extracting table oids from SELECT statement"), + (errmsg("extracting table oids from SELECT statement"), errdetail("ctx->table_names[%d] = \"%s\"", num_oids, ctx->table_names[num_oids]))); } @@ -1223,18 +1266,16 @@ makeRangeVarFromNameList(List *names) * necessary. The returned table name is in static area. So next * call to this function will break previous result. */ -char *make_table_name_from_rangevar(RangeVar *rangevar) +char * +make_table_name_from_rangevar(RangeVar *rangevar) { /* - * Table name. Max size is calculated as follows: - * schema name(POOL_NAMEDATALEN byte) - * + quotation marks for schmea name(2 byte) - * + period(1 byte) - * + table name (POOL_NAMEDATALEN byte) - * + quotation marks for table name(2 byte) - * + NULL(1 byte) + * Table name. Max size is calculated as follows: schema + * name(POOL_NAMEDATALEN byte) + quotation marks for schmea name(2 byte) + + * period(1 byte) + table name (POOL_NAMEDATALEN byte) + quotation marks + * for table name(2 byte) + NULL(1 byte) */ - static char tablename[POOL_NAMEDATALEN*2+1+2*2+1]; + static char tablename[POOL_NAMEDATALEN * 2 + 1 + 2 * 2 + 1]; if (rangevar == NULL) { diff --git a/src/utils/pool_sema.c b/src/utils/pool_sema.c index abe4b55a4..16069fbe6 100644 --- a/src/utils/pool_sema.c +++ b/src/utils/pool_sema.c @@ -51,24 +51,24 @@ IpcSemaphoreKill(int status, Datum semId) union semun semun; struct semid_ds seminfo; - /* - * Is a previously-existing sema segment still existing and in use? - */ + /* + * Is a previously-existing sema segment still existing and in use? + */ semun.buf = &seminfo; - if (semctl(semId, 0, IPC_STAT, semun) < 0 - && (errno == EINVAL || errno == EACCES + if (semctl(semId, 0, IPC_STAT, semun) < 0 + && (errno == EINVAL || errno == EACCES #ifdef EIDRM || errno == EIDRM #endif - )) - return; + )) + return; semun.val = 0; /* unused, but keep compiler quiet */ if (semctl(semId, 0, IPC_RMID) < 0) ereport(LOG, - (errmsg("removing semaphore set"), - errdetail("semctl(%lu, 0, IPC_RMID, ...) failed: %s", semId, strerror(errno)))); + (errmsg("removing semaphore set"), + errdetail("semctl(%lu, 0, IPC_RMID, ...) failed: %s", semId, strerror(errno)))); } /* @@ -84,7 +84,7 @@ pool_semaphore_create(int numSems) if (semId < 0) ereport(FATAL, - (errmsg("Unable to create semaphores:%d error:\"%s\"",numSems,strerror(errno)))); + (errmsg("Unable to create semaphores:%d error:\"%s\"", numSems, strerror(errno)))); on_shmem_exit(IpcSemaphoreKill, semId); @@ -96,8 +96,8 @@ pool_semaphore_create(int numSems) semun.val = 1; if (semctl(semId, i, SETVAL, semun) < 0) ereport(FATAL, - (errmsg("Unable to create semaphores:%d error:\"%s\"",numSems,strerror(errno)), - errdetail("semctl(%d, %d, SETVAL, %d) failed",semId,i,semun.val))); + (errmsg("Unable to create semaphores:%d error:\"%s\"", numSems, strerror(errno)), + errdetail("semctl(%d, %d, SETVAL, %d) failed", semId, i, semun.val))); } } @@ -126,7 +126,7 @@ pool_semaphore_lock(int semNum) if (errStatus < 0) ereport(WARNING, - (errmsg("failed to lock semaphore error:\"%s\"",strerror(errno)))); + (errmsg("failed to lock semaphore error:\"%s\"", strerror(errno)))); } /* @@ -155,5 +155,5 @@ pool_semaphore_unlock(int semNum) if (errStatus < 0) ereport(WARNING, - (errmsg("failed to unlock semaphore error:\"%s\"",strerror(errno)))); + (errmsg("failed to unlock semaphore error:\"%s\"", strerror(errno)))); } diff --git a/src/utils/pool_shmem.c b/src/utils/pool_shmem.c index 71c5a9876..a9f51fd1b 100644 --- a/src/utils/pool_shmem.c +++ b/src/utils/pool_shmem.c @@ -54,8 +54,8 @@ pool_shared_memory_create(size_t size) if (shmid < 0) ereport(FATAL, - (errmsg("could not create shared memory for request size: %ld",size), - errdetail("shared memory creation failed with error \"%s\"",strerror(errno)))); + (errmsg("could not create shared memory for request size: %ld", size), + errdetail("shared memory creation failed with error \"%s\"", strerror(errno)))); /* Register on-exit routine to delete the new segment */ on_shmem_exit(IpcMemoryDelete, shmid); @@ -65,8 +65,8 @@ pool_shared_memory_create(size_t size) if (memAddress == (void *) -1) ereport(FATAL, - (errmsg("could not create shared memory for request size: %ld",size), - errdetail("attach to shared memory [id:%d] failed with reason: \"%s\"",shmid,strerror(errno)))); + (errmsg("could not create shared memory for request size: %ld", size), + errdetail("attach to shared memory [id:%d] failed with reason: \"%s\"", shmid, strerror(errno)))); /* Register on-exit routine to detach new segment before deleting */ @@ -84,7 +84,7 @@ IpcMemoryDetach(int status, Datum shmaddr) { if (shmdt((void *) shmaddr) < 0) ereport(LOG, - (errmsg("removing shared memory segments"), + (errmsg("removing shared memory segments"), errdetail("shmdt(%p) failed: %s", (void *) shmaddr, strerror(errno)))); } @@ -96,24 +96,24 @@ IpcMemoryDetach(int status, Datum shmaddr) static void IpcMemoryDelete(int status, Datum shmId) { - struct shmid_ds shmStat; - - /* - * Is a previously-existing shmem segment still existing and in use? - */ - if (shmctl(shmId, IPC_STAT, &shmStat) < 0 - && (errno == EINVAL || errno == EACCES)) - return; + struct shmid_ds shmStat; + + /* + * Is a previously-existing shmem segment still existing and in use? + */ + if (shmctl(shmId, IPC_STAT, &shmStat) < 0 + && (errno == EINVAL || errno == EACCES)) + return; #ifdef NOT_USED - else if (shmStat.shm_nattch != 0) - return; + else if (shmStat.shm_nattch != 0) + return; #endif if (shmctl(shmId, IPC_RMID, NULL) < 0) ereport(LOG, - (errmsg("deleting shared memory segments"), - errdetail("shmctl(%lu, %d, 0) failed: %s", - shmId, IPC_RMID, strerror(errno)))); + (errmsg("deleting shared memory segments"), + errdetail("shmctl(%lu, %d, 0) failed: %s", + shmId, IPC_RMID, strerror(errno)))); } void diff --git a/src/utils/pool_signal.c b/src/utils/pool_signal.c index 34d762ab1..923f79b1d 100644 --- a/src/utils/pool_signal.c +++ b/src/utils/pool_signal.c @@ -64,9 +64,9 @@ poolinitmask(void) sigfillset(&AuthBlockSig); /* - * Unmark those signals that should never be blocked. Some of these - * signal names don't exist on all platforms. Most do, but might as - * well ifdef them all for consistency... + * Unmark those signals that should never be blocked. Some of these signal + * names don't exist on all platforms. Most do, but might as well ifdef + * them all for consistency... */ #ifdef SIGTRAP sigdelset(&BlockSig, SIGTRAP); @@ -155,21 +155,20 @@ pool_signal(int signo, pool_sighandler_t func) if (sigaction(signo, &act, &oact) < 0) return SIG_ERR; return oact.sa_handler; -#endif /* !HAVE_POSIX_SIGNALS */ +#endif /* !HAVE_POSIX_SIGNALS */ } -int pool_signal_parent(int sig) +int +pool_signal_parent(int sig) { /* - * Check if saved parent pid is same as current parent. - * This is a guard against sending the signal to init process - * pgpool-II parent process crashed and left the child processes - * orphan. - * we make a little exception for pcp process children, since their - * they want to signal the main pgpool-II process but main process is - * not the direct parent + * Check if saved parent pid is same as current parent. This is a guard + * against sending the signal to init process pgpool-II parent process + * crashed and left the child processes orphan. we make a little exception + * for pcp process children, since their they want to signal the main + * pgpool-II process but main process is not the direct parent */ - if(processType != PT_PCP_WORKER && mypid != getppid()) + if (processType != PT_PCP_WORKER && mypid != getppid()) { /* * pgpool parent is no more alive, commiting sucide. @@ -178,9 +177,9 @@ int pool_signal_parent(int sig) (errmsg("pgpool-II main process died unexpectedly. exiting current process"))); } ereport(DEBUG1, - (errmsg("sending signal:%d to the parent process with PID:%d", sig ,mypid))); + (errmsg("sending signal:%d to the parent process with PID:%d", sig, mypid))); return kill(mypid, sig); } -#endif /* WIN32 */ +#endif /* WIN32 */ diff --git a/src/utils/pool_ssl.c b/src/utils/pool_ssl.c index 2105d3ea7..9f61fd7e1 100644 --- a/src/utils/pool_ssl.c +++ b/src/utils/pool_ssl.c @@ -42,9 +42,9 @@ static SSL_CTX *SSL_frontend_context = NULL; static bool SSL_initialized = false; static bool ssl_passwd_cb_called = false; static int ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata); -static int verify_cb(int ok, X509_STORE_CTX *ctx); -static const char * SSLerrmessage(unsigned long ecode); -static void fetch_pool_ssl_cert(POOL_CONNECTION *cp); +static int verify_cb(int ok, X509_STORE_CTX *ctx); +static const char *SSLerrmessage(unsigned long ecode); +static void fetch_pool_ssl_cert(POOL_CONNECTION * cp); #define SSL_RETURN_VOID_IF(cond, msg) \ do { \ @@ -62,16 +62,19 @@ static void fetch_pool_ssl_cert(POOL_CONNECTION *cp); } \ } while (0); -#include <arpa/inet.h> /* for htonl() */ +#include <arpa/inet.h> /* for htonl() */ /* Major/minor codes to negotiate SSL prior to startup packet */ #define NEGOTIATE_SSL_CODE ( 1234<<16 | 5679 ) /* enum flag for differentiating server->client vs client->server SSL */ -enum ssl_conn_type { ssl_conn_clientserver, ssl_conn_serverclient }; +enum ssl_conn_type +{ + ssl_conn_clientserver, ssl_conn_serverclient +}; /* perform per-connection ssl initialization. returns nonzero on error */ -static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype); +static int init_ssl_ctx(POOL_CONNECTION * cp, enum ssl_conn_type conntype); /* OpenSSL error message */ static void perror_ssl(const char *context); @@ -79,45 +82,49 @@ static void perror_ssl(const char *context); /* Attempt to negotiate a secure connection * between pgpool-II and PostgreSQL backends */ -void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) { - int ssl_packet[2] = { htonl(sizeof(int)*2), htonl(NEGOTIATE_SSL_CODE) }; - char server_response; +void +pool_ssl_negotiate_clientserver(POOL_CONNECTION * cp) +{ + int ssl_packet[2] = {htonl(sizeof(int) * 2), htonl(NEGOTIATE_SSL_CODE)}; + char server_response; cp->ssl_active = -1; - if ( (!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_clientserver)) + if ((!pool_config->ssl) || init_ssl_ctx(cp, ssl_conn_clientserver)) return; ereport(DEBUG1, - (errmsg("attempting to negotiate a secure connection"), + (errmsg("attempting to negotiate a secure connection"), errdetail("sending client->server SSL request"))); - pool_write_and_flush(cp, ssl_packet, sizeof(int)*2); + pool_write_and_flush(cp, ssl_packet, sizeof(int) * 2); if (pool_read(cp, &server_response, 1) < 0) { ereport(WARNING, (errmsg("error while attempting to negotiate a secure connection, pool_read failed"))); - return; + return; } ereport(DEBUG1, - (errmsg("attempting to negotiate a secure connection"), + (errmsg("attempting to negotiate a secure connection"), errdetail("client->server SSL response: %c", server_response))); - switch (server_response) { + switch (server_response) + { case 'S': SSL_set_fd(cp->ssl, cp->fd); - SSL_RETURN_VOID_IF( (SSL_connect(cp->ssl) < 0), - "SSL_connect"); + SSL_RETURN_VOID_IF((SSL_connect(cp->ssl) < 0), + "SSL_connect"); cp->ssl_active = 1; break; case 'N': + /* * If backend does not support SSL but pgpool does, we get this. * i.e. This is normal. */ ereport(DEBUG1, - (errmsg("attempting to negotiate a secure connection"), + (errmsg("attempting to negotiate a secure connection"), errdetail("server doesn't want to talk SSL"))); break; default: @@ -131,39 +138,49 @@ void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) { /* attempt to negotiate a secure connection * between frontend and Pgpool-II */ -void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) { +void +pool_ssl_negotiate_serverclient(POOL_CONNECTION * cp) +{ cp->ssl_active = -1; - if ( (!pool_config->ssl) || !SSL_frontend_context) { + if ((!pool_config->ssl) || !SSL_frontend_context) + { pool_write_and_flush(cp, "N", 1); - } else { + } + else + { cp->ssl = SSL_new(SSL_frontend_context); /* write back an "SSL accept" response */ pool_write_and_flush(cp, "S", 1); SSL_set_fd(cp->ssl, cp->fd); - SSL_RETURN_VOID_IF( (SSL_accept(cp->ssl) < 0), "SSL_accept"); + SSL_RETURN_VOID_IF((SSL_accept(cp->ssl) < 0), "SSL_accept"); cp->ssl_active = 1; fetch_pool_ssl_cert(cp); } } -void pool_ssl_close(POOL_CONNECTION *cp) { - if (cp->ssl) { - SSL_shutdown(cp->ssl); - SSL_free(cp->ssl); - } +void +pool_ssl_close(POOL_CONNECTION * cp) +{ + if (cp->ssl) + { + SSL_shutdown(cp->ssl); + SSL_free(cp->ssl); + } - if (cp->ssl_ctx) + if (cp->ssl_ctx) SSL_CTX_free(cp->ssl_ctx); } -int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) { - int n; - int err; +int +pool_ssl_read(POOL_CONNECTION * cp, void *buf, int size) +{ + int n; + int err; - retry: +retry: errno = 0; n = SSL_read(cp->ssl, buf, size); err = SSL_get_error(cp->ssl, n); @@ -205,10 +222,11 @@ int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) { default: ereport(WARNING, (errmsg("ssl read: unrecognized error code: %d", err))); + /* - * We assume that the connection is broken. Returns 0 - * rather than -1 in this case because -1 triggers - * unwanted failover in the caller (pool_read). + * We assume that the connection is broken. Returns 0 rather than + * -1 in this case because -1 triggers unwanted failover in the + * caller (pool_read). */ n = 0; break; @@ -217,10 +235,11 @@ int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) { return n; } -int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size) +int +pool_ssl_write(POOL_CONNECTION * cp, const void *buf, int size) { - int n; - int err; + int n; + int err; retry: errno = 0; @@ -256,8 +275,9 @@ retry: break; default: - ereport(WARNING, - (errmsg("ssl write: unrecognized error code: %d", err))); + ereport(WARNING, + (errmsg("ssl write: unrecognized error code: %d", err))); + /* * We assume that the connection is broken. */ @@ -267,73 +287,89 @@ retry: return n; } -static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype) { - int error = 0; - char *cacert = NULL, *cacert_dir = NULL; +static int +init_ssl_ctx(POOL_CONNECTION * cp, enum ssl_conn_type conntype) +{ + int error = 0; + char *cacert = NULL, + *cacert_dir = NULL; /* initialize SSL members */ #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined (LIBRESSL_VERSION_NUMBER)) - cp->ssl_ctx = SSL_CTX_new(TLS_method()); + cp->ssl_ctx = SSL_CTX_new(TLS_method()); #else - cp->ssl_ctx = SSL_CTX_new(SSLv23_method()); + cp->ssl_ctx = SSL_CTX_new(SSLv23_method()); #endif - SSL_RETURN_ERROR_IF( (! cp->ssl_ctx), "SSL_CTX_new" ); + SSL_RETURN_ERROR_IF((!cp->ssl_ctx), "SSL_CTX_new"); + /* - * Disable OpenSSL's moving-write-buffer sanity check, because it - * causes unnecessary failures in nonblocking send cases. + * Disable OpenSSL's moving-write-buffer sanity check, because it causes + * unnecessary failures in nonblocking send cases. */ SSL_CTX_set_mode(cp->ssl_ctx, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); - if ( conntype == ssl_conn_serverclient) { + if (conntype == ssl_conn_serverclient) + { /* between frontend and pgpool */ error = SSL_CTX_use_certificate_chain_file(cp->ssl_ctx, - pool_config->ssl_cert); - SSL_RETURN_ERROR_IF( (error != 1), "Loading SSL certificate"); + pool_config->ssl_cert); + SSL_RETURN_ERROR_IF((error != 1), "Loading SSL certificate"); error = SSL_CTX_use_PrivateKey_file(cp->ssl_ctx, - pool_config->ssl_key, - SSL_FILETYPE_PEM); - SSL_RETURN_ERROR_IF( (error != 1), "Loading SSL private key"); - } else { + pool_config->ssl_key, + SSL_FILETYPE_PEM); + SSL_RETURN_ERROR_IF((error != 1), "Loading SSL private key"); + } + else + { /* between pgpool and backend */ /* set extra verification if ssl_ca_cert or ssl_ca_cert_dir are set */ if (strlen(pool_config->ssl_ca_cert)) cacert = pool_config->ssl_ca_cert; if (strlen(pool_config->ssl_ca_cert_dir)) cacert_dir = pool_config->ssl_ca_cert_dir; - - if ( cacert || cacert_dir ) { + + if (cacert || cacert_dir) + { error = SSL_CTX_load_verify_locations(cp->ssl_ctx, - cacert, - cacert_dir); + cacert, + cacert_dir); SSL_RETURN_ERROR_IF((error != 1), "SSL verification setup"); SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL); } } cp->ssl = SSL_new(cp->ssl_ctx); - SSL_RETURN_ERROR_IF( (! cp->ssl), "SSL_new"); + SSL_RETURN_ERROR_IF((!cp->ssl), "SSL_new"); return 0; } -static void perror_ssl(const char *context) { +static void +perror_ssl(const char *context) +{ unsigned long err; static const char *no_err_reason = "no SSL error reported"; const char *reason; err = ERR_get_error(); - if (! err) { + if (!err) + { reason = no_err_reason; - } else { + } + else + { reason = ERR_reason_error_string(err); } - if (reason != NULL) { + if (reason != NULL) + { ereport(LOG, - (errmsg("pool_ssl: \"%s\": \"%s\"", context, reason))); - } else { + (errmsg("pool_ssl: \"%s\": \"%s\"", context, reason))); + } + else + { ereport(LOG, (errmsg("pool_ssl: \"%s\": Unknown SSL error %lu", context, err))); } @@ -367,28 +403,33 @@ SSLerrmessage(unsigned long ecode) /* * Return true if SSL layer has any pending data in buffer */ -bool pool_ssl_pending(POOL_CONNECTION *cp) +bool +pool_ssl_pending(POOL_CONNECTION * cp) { if (cp->ssl_active > 0 && SSL_pending(cp->ssl) > 0) return true; return false; } -static void fetch_pool_ssl_cert(POOL_CONNECTION *cp) +static void +fetch_pool_ssl_cert(POOL_CONNECTION * cp) { - int len; - X509 *peer = SSL_get_peer_certificate(cp->ssl); + int len; + X509 *peer = SSL_get_peer_certificate(cp->ssl); + cp->peer = peer; if (peer) { ereport(DEBUG1, (errmsg("got the SSL certificate"))); - len = X509_NAME_get_text_by_NID(X509_get_subject_name(peer),NID_commonName, NULL, 0); + len = X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, NULL, 0); if (len != -1) { - char *peer_cn; + char *peer_cn; + peer_cn = palloc(len + 1); - int r = X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_cn, len + 1); + int r = X509_NAME_get_text_by_NID(X509_get_subject_name(peer), NID_commonName, peer_cn, len + 1); + peer_cn[len] = '\0'; if (r != len) { @@ -397,7 +438,7 @@ static void fetch_pool_ssl_cert(POOL_CONNECTION *cp) return; } cp->client_cert_loaded = true; - cp->cert_cn = MemoryContextStrdup(TopMemoryContext,peer_cn); + cp->cert_cn = MemoryContextStrdup(TopMemoryContext, peer_cn); pfree(peer_cn); } else @@ -430,6 +471,7 @@ ssl_passwd_cb(char *buf, int size, int rwflag, void *userdata) buf[0] = '\0'; return 0; } + /* * Certificate verification callback * @@ -614,7 +656,8 @@ SSL_ServerSide_init(void) */ if (pool_config->ssl_ca_cert) { - char *cacert = NULL, *cacert_dir = NULL; + char *cacert = NULL, + *cacert_dir = NULL; if (strlen(pool_config->ssl_ca_cert)) cacert = pool_config->ssl_ca_cert; @@ -629,6 +672,7 @@ SSL_ServerSide_init(void) pool_config->ssl_ca_cert, SSLerrmessage(ERR_get_error())))); goto error; } + /* * Always ask for SSL client cert, but don't fail if it's not * presented. We might fail such connections later, depending on what @@ -663,16 +707,21 @@ error: return -1; } -#else /* USE_SSL: wrap / no-op ssl functionality if it's not available */ +#else /* USE_SSL: wrap / no-op ssl functionality if + * it's not available */ -void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) { +void +pool_ssl_negotiate_serverclient(POOL_CONNECTION * cp) +{ ereport(DEBUG1, (errmsg("SSL is requested but SSL support is not available"))); pool_write_and_flush(cp, "N", 1); cp->ssl_active = -1; } -void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) { +void +pool_ssl_negotiate_clientserver(POOL_CONNECTION * cp) +{ ereport(DEBUG1, (errmsg("SSL is requested but SSL support is not available"))); @@ -680,32 +729,42 @@ void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) { cp->ssl_active = -1; } -void pool_ssl_close(POOL_CONNECTION *cp) { return; } +void +pool_ssl_close(POOL_CONNECTION * cp) +{ + return; +} -int pool_ssl_read(POOL_CONNECTION *cp, void *buf, int size) { +int +pool_ssl_read(POOL_CONNECTION * cp, void *buf, int size) +{ ereport(WARNING, (errmsg("pool_ssl: SSL i/o called but SSL support is not available"))); notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); child_exit(POOL_EXIT_AND_RESTART); - return -1; /* never reached */ + return -1; /* never reached */ } -int pool_ssl_write(POOL_CONNECTION *cp, const void *buf, int size) { +int +pool_ssl_write(POOL_CONNECTION * cp, const void *buf, int size) +{ ereport(WARNING, (errmsg("pool_ssl: SSL i/o called but SSL support is not available"))); notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); child_exit(POOL_EXIT_AND_RESTART); - return -1; /* never reached */ + return -1; /* never reached */ } -int SSL_ServerSide_init(void) +int +SSL_ServerSide_init(void) { return 0; } -bool pool_ssl_pending(POOL_CONNECTION *cp) +bool +pool_ssl_pending(POOL_CONNECTION * cp) { return false; } -#endif /* USE_SSL */ +#endif /* USE_SSL */ diff --git a/src/utils/pool_stream.c b/src/utils/pool_stream.c index 3edaf590b..63149d499 100644 --- a/src/utils/pool_stream.c +++ b/src/utils/pool_stream.c @@ -43,41 +43,42 @@ #include "utils/pool_stream.h" #include "pool_config.h" -static int mystrlen(char *str, int upper, int *flag); -static int mystrlinelen(char *str, int upper, int *flag); -static int save_pending_data(POOL_CONNECTION *cp, void *data, int len); -static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len); +static int mystrlen(char *str, int upper, int *flag); +static int mystrlinelen(char *str, int upper, int *flag); +static int save_pending_data(POOL_CONNECTION * cp, void *data, int len); +static int consume_pending_data(POOL_CONNECTION * cp, void *data, int len); static MemoryContext SwitchToConnectionContext(bool backend_connection); #ifdef DEBUG static void dump_buffer(char *buf, int len); #endif -static int pool_write_flush(POOL_CONNECTION *cp, void *buf, int len); +static int pool_write_flush(POOL_CONNECTION * cp, void *buf, int len); static MemoryContext - SwitchToConnectionContext(bool backend_connection) +SwitchToConnectionContext(bool backend_connection) { - /* - * backend connection can live as long as process life, - * while the frontend connection is only for one session life. - * So we create backend connection in long living memory context - */ - if(backend_connection) - return MemoryContextSwitchTo(TopMemoryContext); - else - return MemoryContextSwitchTo(ProcessLoopContext); + /* + * backend connection can live as long as process life, while the frontend + * connection is only for one session life. So we create backend + * connection in long living memory context + */ + if (backend_connection) + return MemoryContextSwitchTo(TopMemoryContext); + else + return MemoryContextSwitchTo(ProcessLoopContext); } /* * open read/write file descriptors. * returns POOL_CONNECTION on success otherwise NULL. */ -POOL_CONNECTION *pool_open(int fd, bool backend_connection) +POOL_CONNECTION * +pool_open(int fd, bool backend_connection) { POOL_CONNECTION *cp; - MemoryContext oldContext = SwitchToConnectionContext(backend_connection); + MemoryContext oldContext = SwitchToConnectionContext(backend_connection); - cp = (POOL_CONNECTION *)palloc0(sizeof(POOL_CONNECTION)); + cp = (POOL_CONNECTION *) palloc0(sizeof(POOL_CONNECTION)); /* initialize write buffer */ cp->wbuf = palloc(WRITEBUFSZ); @@ -99,7 +100,7 @@ POOL_CONNECTION *pool_open(int fd, bool backend_connection) cp->fd = fd; cp->socket_state = POOL_SOCKET_VALID; - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); return cp; } @@ -107,7 +108,8 @@ POOL_CONNECTION *pool_open(int fd, bool backend_connection) /* * close read/write file descriptors. */ -void pool_close(POOL_CONNECTION *cp) +void +pool_close(POOL_CONNECTION * cp) { /* * shutdown connection to the client so that pgpool is not blocked @@ -131,26 +133,29 @@ void pool_close(POOL_CONNECTION *cp) pfree(cp); } -void pool_read_with_error(POOL_CONNECTION *cp, void *buf, int len, - const char* err_context ) +void +pool_read_with_error(POOL_CONNECTION * cp, void *buf, int len, + const char *err_context) { if (pool_read(cp, buf, len) < 0) { - ereport(ERROR, - (errmsg("failed to read data of length %d from DB node: %d",len,cp->db_node_id), - errdetail("error occurred when reading: %s",err_context?err_context:""))); + ereport(ERROR, + (errmsg("failed to read data of length %d from DB node: %d", len, cp->db_node_id), + errdetail("error occurred when reading: %s", err_context ? err_context : ""))); } } + /* * read len bytes from cp * returns 0 on success otherwise throws an ereport. */ -int pool_read(POOL_CONNECTION *cp, void *buf, int len) +int +pool_read(POOL_CONNECTION * cp, void *buf, int len) { static char readbuf[READBUFSZ]; - int consume_size; - int readlen; + int consume_size; + int readlen; consume_size = consume_pending_data(cp, buf, len); len -= consume_size; @@ -162,35 +167,35 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) { if (!IS_MASTER_NODE_ID(cp->db_node_id) && (getpid() != mypid)) { - ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("data is not ready in DB node"))); + ereport(FATAL, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("data is not ready in DB node"))); } else { - ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("pool_check_fd call failed with an error \"%s\"", strerror(errno)))); + ereport(ERROR, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("pool_check_fd call failed with an error \"%s\"", strerror(errno)))); } } if (cp->ssl_active > 0) { - readlen = pool_ssl_read(cp, readbuf, READBUFSZ); + readlen = pool_ssl_read(cp, readbuf, READBUFSZ); } else { - readlen = read(cp->fd, readbuf, READBUFSZ); - if (cp->isbackend) - { - ereport(DEBUG5, - (errmsg("pool_read: read %d bytes from backend %d", - readlen, cp->db_node_id))); + readlen = read(cp->fd, readbuf, READBUFSZ); + if (cp->isbackend) + { + ereport(DEBUG5, + (errmsg("pool_read: read %d bytes from backend %d", + readlen, cp->db_node_id))); #ifdef DEBUG - dump_buffer(readbuf, readlen); + dump_buffer(readbuf, readlen); #endif - } + } } if (readlen == -1) @@ -198,7 +203,7 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) if (errno == EINTR || errno == EAGAIN) { ereport(DEBUG5, - (errmsg("read on socket failed with error :\"%s\"",strerror(errno)), + (errmsg("read on socket failed with error :\"%s\"", strerror(errno)), errdetail("retrying..."))); continue; } @@ -210,33 +215,36 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) { cp->con_info->swallow_termination = 0; ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("pg_terminate_backend was called on the backend"))); } - /* if fail_over_on_backend_error is true, then trigger failover */ + /* + * if fail_over_on_backend_error is true, then trigger + * failover + */ if (pool_config->fail_over_on_backend_error) { notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); - /* If we are in the main process, we will not exit */ + /* If we are in the main process, we will not exit */ child_exit(POOL_EXIT_AND_RESTART); ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("socket read failed with an error \"%s\"", strerror(errno)))); } else { ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("socket read failed with an error \"%s\"", strerror(errno)))); } } else { - ereport(FRONTEND_ERROR, - (errmsg("unable to read data from frontend"), - errdetail("socket read failed with an error \"%s\"", strerror(errno)))); + ereport(FRONTEND_ERROR, + (errmsg("unable to read data from frontend"), + errdetail("socket read failed with an error \"%s\"", strerror(errno)))); } } else if (readlen == 0) @@ -246,28 +254,29 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) { if (processType == PT_MAIN || processType == PT_HEALTH_CHECK) ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("EOF encountered with backend"))); - ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("EOF encountered with backend"))); + ereport(FATAL, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("EOF encountered with backend"))); } else { /* - * if backend offers authentication method, frontend could close connection + * if backend offers authentication method, frontend could + * close connection */ - ereport(FRONTEND_ERROR, - (errmsg("unable to read data from frontend"), - errdetail("EOF encountered with frontend"))); + ereport(FRONTEND_ERROR, + (errmsg("unable to read data from frontend"), + errdetail("EOF encountered with frontend"))); } } if (len < readlen) { /* overrun. we need to save remaining data to pending buffer */ - save_pending_data(cp, readbuf+len, readlen-len); + save_pending_data(cp, readbuf + len, readlen - len); memmove(buf, readbuf, len); break; } @@ -284,20 +293,21 @@ int pool_read(POOL_CONNECTION *cp, void *buf, int len) * read exactly len bytes from cp * returns buffer address on success otherwise NULL. */ -char *pool_read2(POOL_CONNECTION *cp, int len) +char * +pool_read2(POOL_CONNECTION * cp, int len) { - char *buf; - int req_size; - int alloc_size; - int consume_size; - int readlen; - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + char *buf; + int req_size; + int alloc_size; + int consume_size; + int readlen; + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); req_size = cp->len + len; if (req_size > cp->bufsz2) { - alloc_size = ((req_size+1)/READBUFSZ+1)*READBUFSZ; + alloc_size = ((req_size + 1) / READBUFSZ + 1) * READBUFSZ; cp->buf2 = repalloc(cp->buf2, alloc_size); cp->bufsz2 = alloc_size; } @@ -314,30 +324,30 @@ char *pool_read2(POOL_CONNECTION *cp, int len) { if (!IS_MASTER_NODE_ID(cp->db_node_id)) { - ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("data is not ready in DB node"))); - + ereport(FATAL, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("data is not ready in DB node"))); + } else { - ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("pool_check_fd call failed with an error \"%s\"", strerror(errno)))); - } + ereport(ERROR, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("pool_check_fd call failed with an error \"%s\"", strerror(errno)))); + } } if (cp->ssl_active > 0) { - readlen = pool_ssl_read(cp, buf, len); + readlen = pool_ssl_read(cp, buf, len); } else { - readlen = read(cp->fd, buf, len); - if (cp->isbackend) - ereport(DEBUG5, - (errmsg("pool_read2: read %d bytes from backend %d", - readlen, cp->db_node_id))); + readlen = read(cp->fd, buf, len); + if (cp->isbackend) + ereport(DEBUG5, + (errmsg("pool_read2: read %d bytes from backend %d", + readlen, cp->db_node_id))); } if (readlen == -1) @@ -345,7 +355,7 @@ char *pool_read2(POOL_CONNECTION *cp, int len) if (errno == EINTR || errno == EAGAIN) { ereport(DEBUG5, - (errmsg("read on socket failed with error :\"%s\"",strerror(errno)), + (errmsg("read on socket failed with error :\"%s\"", strerror(errno)), errdetail("retrying..."))); continue; } @@ -357,32 +367,35 @@ char *pool_read2(POOL_CONNECTION *cp, int len) { cp->con_info->swallow_termination = 0; ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("pg_terminate_backend was called on the backend"))); } - /* if fail_over_on_backend_error is true, then trigger failover */ + /* + * if fail_over_on_backend_error is true, then trigger + * failover + */ if (pool_config->fail_over_on_backend_error) { notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); child_exit(POOL_EXIT_AND_RESTART); - /* we are in main process */ - ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("socket read failed with an error \"%s\"", strerror(errno)))); + /* we are in main process */ + ereport(ERROR, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("socket read failed with an error \"%s\"", strerror(errno)))); } else { - ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("do not failover because fail_over_on_backend_error is off"))); + ereport(ERROR, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("do not failover because fail_over_on_backend_error is off"))); } } else { - ereport(ERROR, - (errmsg("unable to read data from frontend"), - errdetail("socket read function returned -1"))); + ereport(ERROR, + (errmsg("unable to read data from frontend"), + errdetail("socket read function returned -1"))); } } else if (readlen == 0) @@ -390,18 +403,19 @@ char *pool_read2(POOL_CONNECTION *cp, int len) cp->socket_state = POOL_SOCKET_EOF; if (cp->isbackend) { - ereport(ERROR, - (errmsg("unable to read data from backend"), - errdetail("EOF read on socket"))); + ereport(ERROR, + (errmsg("unable to read data from backend"), + errdetail("EOF read on socket"))); } else { /* - * if backend offers authentication method, frontend could close connection + * if backend offers authentication method, frontend could + * close connection */ - ereport(ERROR, - (errmsg("unable to read data from frontend"), - errdetail("EOF read on socket"))); + ereport(ERROR, + (errmsg("unable to read data from frontend"), + errdetail("EOF read on socket"))); } } @@ -409,7 +423,7 @@ char *pool_read2(POOL_CONNECTION *cp, int len) buf += readlen; len -= readlen; } - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); return cp->buf2; } @@ -417,19 +431,20 @@ char *pool_read2(POOL_CONNECTION *cp, int len) * write len bytes to cp the write buffer. * returns 0 on success otherwise -1. */ -int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len) +int +pool_write_noerror(POOL_CONNECTION * cp, void *buf, int len) { if (len < 0) - return -1; + return -1; if (cp->no_forward) return 0; if (len == 1 && cp->isbackend) { - char c; + char c; - c = ((char *)buf)[0]; + c = ((char *) buf)[0]; ereport(DEBUG5, (errmsg("pool_write: to backend: %d kind:%c", cp->db_node_id, c))); @@ -437,9 +452,9 @@ int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len) if (!cp->isbackend) { - char c; + char c; - c = ((char *)buf)[0]; + c = ((char *) buf)[0]; if (len == 1) ereport(DEBUG5, @@ -448,10 +463,10 @@ int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len) ereport(DEBUG5, (errmsg("pool_write: to frontend: length:%d po:%d", len, cp->wbufpo))); } - + while (len > 0) { - int remainder = WRITEBUFSZ - cp->wbufpo; + int remainder = WRITEBUFSZ - cp->wbufpo; /* * If requested data cannot be added to the write buffer, flush the @@ -471,18 +486,18 @@ int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len) if (cp->wbufpo >= WRITEBUFSZ) { /* - * Write buffer is full. so flush buffer. - * wbufpo is reset in pool_flush_it(). + * Write buffer is full. so flush buffer. wbufpo is reset in + * pool_flush_it(). */ if (pool_flush_it(cp) == -1) return -1; - remainder = WRITEBUFSZ; + remainder = WRITEBUFSZ; } - + /* check buffer size */ remainder = Min(remainder, len); - memcpy(cp->wbuf+cp->wbufpo, buf, remainder); + memcpy(cp->wbuf + cp->wbufpo, buf, remainder); cp->wbufpo += remainder; buf += remainder; len -= remainder; @@ -494,19 +509,20 @@ int pool_write_noerror(POOL_CONNECTION *cp, void *buf, int len) * write len bytes to cp the write buffer. * returns 0 on success otherwise ereport. */ -int pool_write(POOL_CONNECTION *cp, void *buf, int len) +int +pool_write(POOL_CONNECTION * cp, void *buf, int len) { if (len < 0) - ereport(ERROR, - (errmsg("unable to write data to %s",cp->isbackend?"backend":"frontend"), - errdetail("invalid data size: %d", len))); - - if(pool_write_noerror(cp,buf,len)) - ereport(ERROR, - (errmsg("unable to write data to %s",cp->isbackend?"backend":"frontend"), - errdetail("pool_flush failed"))); - - return 0; + ereport(ERROR, + (errmsg("unable to write data to %s", cp->isbackend ? "backend" : "frontend"), + errdetail("invalid data size: %d", len))); + + if (pool_write_noerror(cp, buf, len)) + ereport(ERROR, + (errmsg("unable to write data to %s", cp->isbackend ? "backend" : "frontend"), + errdetail("pool_flush failed"))); + + return 0; } @@ -514,11 +530,13 @@ int pool_write(POOL_CONNECTION *cp, void *buf, int len) * Direct write. * This function does not throws an ereport in case of an error */ -static int pool_write_flush(POOL_CONNECTION *cp, void *buf, int len) +static int +pool_write_flush(POOL_CONNECTION * cp, void *buf, int len) { - int sts; - int wlen; - int offset; + int sts; + int wlen; + int offset; + wlen = len; ereport(DEBUG5, @@ -537,11 +555,11 @@ static int pool_write_flush(POOL_CONNECTION *cp, void *buf, int len) if (cp->ssl_active > 0) { - sts = pool_ssl_write(cp, buf+offset, wlen); + sts = pool_ssl_write(cp, buf + offset, wlen); } else { - sts = write(cp->fd, buf+offset, wlen); + sts = write(cp->fd, buf + offset, wlen); } if (sts >= 0) @@ -579,17 +597,18 @@ static int pool_write_flush(POOL_CONNECTION *cp, void *buf, int len) else { - /* If this is the backend stream, report error. Otherwise - * just report debug message. + /* + * If this is the backend stream, report error. Otherwise just + * report debug message. */ if (cp->isbackend) ereport(WARNING, - (errmsg("write on backend %d failed with error :\"%s\"",cp->db_node_id,strerror(errno)), - errdetail("while trying to write data from offset: %d wlen: %d",offset, wlen))); + (errmsg("write on backend %d failed with error :\"%s\"", cp->db_node_id, strerror(errno)), + errdetail("while trying to write data from offset: %d wlen: %d", offset, wlen))); else ereport(DEBUG5, - (errmsg("write on frontend failed with error :\"%s\"",strerror(errno)), - errdetail("while trying to write data from offset: %d wlen: %d",offset, wlen))); + (errmsg("write on frontend failed with error :\"%s\"", strerror(errno)), + errdetail("while trying to write data from offset: %d wlen: %d", offset, wlen))); return -1; } } @@ -601,11 +620,13 @@ static int pool_write_flush(POOL_CONNECTION *cp, void *buf, int len) * flush write buffer * This function does not throws an ereport in case of an error */ -int pool_flush_it(POOL_CONNECTION *cp) +int +pool_flush_it(POOL_CONNECTION * cp) { - int sts; - int wlen; - int offset; + int sts; + int wlen; + int offset; + wlen = cp->wbufpo; ereport(DEBUG5, @@ -624,11 +645,11 @@ int pool_flush_it(POOL_CONNECTION *cp) if (cp->ssl_active > 0) { - sts = pool_ssl_write(cp, cp->wbuf + offset, wlen); + sts = pool_ssl_write(cp, cp->wbuf + offset, wlen); } else { - sts = write(cp->fd, cp->wbuf + offset, wlen); + sts = write(cp->fd, cp->wbuf + offset, wlen); } if (sts >= 0) @@ -667,17 +688,18 @@ int pool_flush_it(POOL_CONNECTION *cp) else { - /* If this is the backend stream, report error. Otherwise - * just report debug message. + /* + * If this is the backend stream, report error. Otherwise just + * report debug message. */ if (cp->isbackend) ereport(WARNING, - (errmsg("write on backend %d failed with error :\"%s\"",cp->db_node_id,strerror(errno)), - errdetail("while trying to write data from offset: %d wlen: %d",offset, wlen))); + (errmsg("write on backend %d failed with error :\"%s\"", cp->db_node_id, strerror(errno)), + errdetail("while trying to write data from offset: %d wlen: %d", offset, wlen))); else ereport(DEBUG5, - (errmsg("write on frontend failed with error :\"%s\"",strerror(errno)), - errdetail("while trying to write data from offset: %d wlen: %d",offset, wlen))); + (errmsg("write on frontend failed with error :\"%s\"", strerror(errno)), + errdetail("while trying to write data from offset: %d wlen: %d", offset, wlen))); cp->wbufpo = 0; return -1; } @@ -691,7 +713,8 @@ int pool_flush_it(POOL_CONNECTION *cp) /* * flush write buffer and degenerate/failover if error occurs */ -int pool_flush(POOL_CONNECTION *cp) +int +pool_flush(POOL_CONNECTION * cp) { if (pool_flush_it(cp) == -1) { @@ -701,7 +724,7 @@ int pool_flush(POOL_CONNECTION *cp) { cp->con_info->swallow_termination = 0; ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("pg_terminate_backend was called on the backend"))); } @@ -710,7 +733,7 @@ int pool_flush(POOL_CONNECTION *cp) { notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); ereport(LOG, - (errmsg("unable to flush data to backend"), + (errmsg("unable to flush data to backend"), errdetail("do not failover because I am the main process"))); child_exit(POOL_EXIT_AND_RESTART); @@ -718,25 +741,25 @@ int pool_flush(POOL_CONNECTION *cp) } else { - ereport(ERROR, - (errmsg("unable to flush data to backend"), - errdetail("do not failover because fail_over_on_backend_error is off"))); + ereport(ERROR, + (errmsg("unable to flush data to backend"), + errdetail("do not failover because fail_over_on_backend_error is off"))); } } else { /* * If we are in replication mode, we need to continue the - * processing with backends to keep consistency among - * backends, thus ignore error. + * processing with backends to keep consistency among backends, + * thus ignore error. */ if (REPLICATION) - ereport(NOTICE, - (errmsg("unable to flush data to frontend"), - errdetail("pgpool is in replication mode, ignoring error to keep consistency among backends"))); + ereport(NOTICE, + (errmsg("unable to flush data to frontend"), + errdetail("pgpool is in replication mode, ignoring error to keep consistency among backends"))); else - ereport(FRONTEND_ERROR, - (errmsg("unable to flush data to frontend"))); + ereport(FRONTEND_ERROR, + (errmsg("unable to flush data to frontend"))); } } @@ -746,58 +769,60 @@ int pool_flush(POOL_CONNECTION *cp) /* * same as pool_flush() but returns -ve value instead of ereport in case of failure */ -int pool_flush_noerror(POOL_CONNECTION *cp) +int +pool_flush_noerror(POOL_CONNECTION * cp) { - if (pool_flush_it(cp) == -1) - { - if (cp->isbackend) - { + if (pool_flush_it(cp) == -1) + { + if (cp->isbackend) + { if (cp->con_info && cp->con_info->swallow_termination == 1) { cp->con_info->swallow_termination = 0; ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("pg_terminate_backend was called on the backend"))); } - /* if fail_over_on_backend_erro is true, then trigger failover */ - if (pool_config->fail_over_on_backend_error) - { - notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); - child_exit(POOL_EXIT_AND_RESTART); + /* if fail_over_on_backend_erro is true, then trigger failover */ + if (pool_config->fail_over_on_backend_error) + { + notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); + child_exit(POOL_EXIT_AND_RESTART); ereport(LOG, - (errmsg("unable to flush data to backend"), + (errmsg("unable to flush data to backend"), errdetail("do not failover because I am the main process"))); - return -1; - } - else - { + return -1; + } + else + { ereport(LOG, - (errmsg("unable to flush data to backend"), - errdetail("do not failover because fail_over_on_backend_error is off"))); - return -1; - } - } - else - { - /* - * If we are in replication mode, we need to continue the - * processing with backends to keep consistency among - * backends, thus ignore error. - */ - if (REPLICATION) - return 0; - else - return -1; - } - } - return 0; + (errmsg("unable to flush data to backend"), + errdetail("do not failover because fail_over_on_backend_error is off"))); + return -1; + } + } + else + { + /* + * If we are in replication mode, we need to continue the + * processing with backends to keep consistency among backends, + * thus ignore error. + */ + if (REPLICATION) + return 0; + else + return -1; + } + } + return 0; } /* * combo of pool_write and pool_flush */ -void pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len) +void +pool_write_and_flush(POOL_CONNECTION * cp, void *buf, int len) { pool_write(cp, buf, len); pool_flush(cp); @@ -806,11 +831,13 @@ void pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len) /* * same as pool_write_and_flush() but does not throws ereport when error occures */ -int pool_write_and_flush_noerror(POOL_CONNECTION *cp, void *buf, int len) +int +pool_write_and_flush_noerror(POOL_CONNECTION * cp, void *buf, int len) { - int ret; - ret = pool_write_noerror(cp,buf,len); - if(ret == 0) + int ret; + + ret = pool_write_noerror(cp, buf, len); + if (ret == 0) return pool_flush_noerror(cp); return ret; } @@ -819,14 +846,15 @@ int pool_write_and_flush_noerror(POOL_CONNECTION *cp, void *buf, int len) * read a string until EOF or NULL is encountered. * if line is not 0, read until new line is encountered. */ -char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) +char * +pool_read_string(POOL_CONNECTION * cp, int *len, int line) { - int readp; - int readsize; - int readlen; - int strlength; - int flag; - int consume_size; + int readp; + int readsize; + int readlen; + int strlength; + int flag; + int consume_size; #ifdef DEBUG static char pbuf[READBUFSZ]; @@ -838,9 +866,10 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) /* initialize read buffer */ if (cp->sbufsz == 0) { - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + cp->sbuf = palloc(READBUFSZ); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); cp->sbufsz = READBUFSZ; *cp->sbuf = '\0'; @@ -850,17 +879,18 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) if (cp->len) { if (line) - strlength = mystrlinelen(cp->hp+cp->po, cp->len, &flag); + strlength = mystrlinelen(cp->hp + cp->po, cp->len, &flag); else - strlength = mystrlen(cp->hp+cp->po, cp->len, &flag); + strlength = mystrlen(cp->hp + cp->po, cp->len, &flag); /* buffer is too small? */ if ((strlength + 1) > cp->sbufsz) { - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); - cp->sbufsz = ((strlength+1)/READBUFSZ+1)*READBUFSZ; + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + + cp->sbufsz = ((strlength + 1) / READBUFSZ + 1) * READBUFSZ; cp->sbuf = repalloc(cp->sbuf, cp->sbufsz); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); } /* consume pending and save to read string buffer */ @@ -871,8 +901,9 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) /* is the string null terminated? */ if (consume_size == strlength && !flag) { - /* not null or line terminated. - * we need to read more since we have not encountered NULL or new line yet + /* + * not null or line terminated. we need to read more since we have + * not encountered NULL or new line yet */ readsize = cp->sbufsz - strlength; readp = strlength; @@ -880,12 +911,13 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) else { ereport(DEBUG5, - (errmsg("reading string data"), + (errmsg("reading string data"), errdetail("read all from pending data. po:%d len:%d", cp->po, cp->len))); return cp->sbuf; } - } else + } + else { readsize = cp->sbufsz; } @@ -896,26 +928,26 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) { if (!IS_MASTER_NODE_ID(cp->db_node_id)) { - ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("data is not ready in DB node"))); - + ereport(FATAL, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("data is not ready in DB node"))); + } else { - ereport(ERROR, - (errmsg("unable to read data from DB node %d",cp->db_node_id), - errdetail("pool_check_fd call failed with an error \"%s\"", strerror(errno)))); - } + ereport(ERROR, + (errmsg("unable to read data from DB node %d", cp->db_node_id), + errdetail("pool_check_fd call failed with an error \"%s\"", strerror(errno)))); + } } if (cp->ssl_active > 0) { - readlen = pool_ssl_read(cp, cp->sbuf+readp, readsize); + readlen = pool_ssl_read(cp, cp->sbuf + readp, readsize); } else { - readlen = read(cp->fd, cp->sbuf+readp, readsize); + readlen = read(cp->fd, cp->sbuf + readp, readsize); } if (readlen == -1) @@ -927,21 +959,21 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) { cp->con_info->swallow_termination = 0; ereport(FATAL, - (errmsg("unable to read data from DB node %d",cp->db_node_id), + (errmsg("unable to read data from DB node %d", cp->db_node_id), errdetail("pg_terminate_backend was called on the backend"))); } notice_backend_error(cp->db_node_id, REQ_DETAIL_SWITCHOVER); child_exit(POOL_EXIT_AND_RESTART); - ereport(ERROR, - (errmsg("unable to read data from frontend"), - errdetail("socket read function returned -1"))); + ereport(ERROR, + (errmsg("unable to read data from frontend"), + errdetail("socket read function returned -1"))); } else { - ereport(ERROR, - (errmsg("unable to read data from frontend"), - errdetail("socket read function returned -1"))); + ereport(ERROR, + (errmsg("unable to read data from frontend"), + errdetail("socket read function returned -1"))); } } @@ -951,24 +983,24 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) * just returns an error, not trigger failover or degeneration */ cp->socket_state = POOL_SOCKET_EOF; - ereport(ERROR, - (errmsg("unable to read data from %s",cp->isbackend?"backend":"frontend"), - errdetail("EOF read on socket"))); + ereport(ERROR, + (errmsg("unable to read data from %s", cp->isbackend ? "backend" : "frontend"), + errdetail("EOF read on socket"))); } /* check overrun */ if (line) - strlength = mystrlinelen(cp->sbuf+readp, readlen, &flag); + strlength = mystrlinelen(cp->sbuf + readp, readlen, &flag); else - strlength = mystrlen(cp->sbuf+readp, readlen, &flag); + strlength = mystrlen(cp->sbuf + readp, readlen, &flag); if (strlength < readlen) { - save_pending_data(cp, cp->sbuf+readp+strlength, readlen-strlength); + save_pending_data(cp, cp->sbuf + readp + strlength, readlen - strlength); *len += strlength; ereport(DEBUG5, - (errmsg("reading string data"), + (errmsg("reading string data"), errdetail("total read %d with pending data po:%d len:%d", *len, cp->po, cp->len))); return cp->sbuf; } @@ -980,7 +1012,7 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) { /* ok we have read all data */ ereport(DEBUG5, - (errmsg("reading string data"), + (errmsg("reading string data"), errdetail("all data read: total read %d", *len))); break; } @@ -988,12 +1020,13 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) readp += readlen; readsize = READBUFSZ; - if ((*len+readsize) > cp->sbufsz) + if ((*len + readsize) > cp->sbufsz) { cp->sbufsz += READBUFSZ; - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + cp->sbuf = repalloc(cp->sbuf, cp->sbufsz); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); } } return cp->sbuf; @@ -1002,7 +1035,8 @@ char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) /* * Set db node id to connection. */ -void pool_set_db_node_id(POOL_CONNECTION *con, int db_node_id) +void +pool_set_db_node_id(POOL_CONNECTION * con, int db_node_id) { if (!con) return; @@ -1018,20 +1052,21 @@ void pool_set_db_node_id(POOL_CONNECTION *con, int db_node_id) * mystrlen("abc", 4) returns 4 * mystrlen("abc", 5) returns 4 */ -static int mystrlen(char *str, int upper, int *flag) +static int +mystrlen(char *str, int upper, int *flag) { - int len; + int len; *flag = 0; - for (len = 0;len < upper; len++, str++) + for (len = 0; len < upper; len++, str++) { - if (!*str) - { + if (!*str) + { len++; *flag = 1; break; - } + } } return len; } @@ -1048,20 +1083,21 @@ static int mystrlen(char *str, int upper, int *flag) * mystrlinelen("abcd\nefg", 5) returns 5 * mystrlinelen("abcd\nefg", 6) returns 5 */ -static int mystrlinelen(char *str, int upper, int *flag) +static int +mystrlinelen(char *str, int upper, int *flag) { - int len; + int len; *flag = 0; - for (len = 0;len < upper; len++, str++) + for (len = 0; len < upper; len++, str++) { - if (!*str || *str == '\n') - { + if (!*str || *str == '\n') + { len++; *flag = 1; break; - } + } } return len; } @@ -1069,11 +1105,12 @@ static int mystrlinelen(char *str, int upper, int *flag) /* * save pending data */ -static int save_pending_data(POOL_CONNECTION *cp, void *data, int len) +static int +save_pending_data(POOL_CONNECTION * cp, void *data, int len) { - int reqlen; - size_t realloc_size; - char *p; + int reqlen; + size_t realloc_size; + char *p; /* to be safe */ if (cp->len == 0) @@ -1085,11 +1122,12 @@ static int save_pending_data(POOL_CONNECTION *cp, void *data, int len) if (reqlen > cp->bufsz) { /* too small, enlarge it */ - realloc_size = (reqlen/READBUFSZ+1)*READBUFSZ; + realloc_size = (reqlen / READBUFSZ + 1) * READBUFSZ; + + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); p = repalloc(cp->hp, realloc_size); - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); cp->bufsz = realloc_size; cp->hp = p; @@ -1104,9 +1142,10 @@ static int save_pending_data(POOL_CONNECTION *cp, void *data, int len) /* * consume pending data. returns actually consumed data length. */ -static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len) +static int +consume_pending_data(POOL_CONNECTION * cp, void *data, int len) { - int consume_size; + int consume_size; if (cp->len <= 0) return 0; @@ -1126,11 +1165,12 @@ static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len) /* * pool_unread: Put back data to input buffer */ -int pool_unread(POOL_CONNECTION *cp, void *data, int len) +int +pool_unread(POOL_CONNECTION * cp, void *data, int len) { - void *p = cp->hp; - int n = cp->len + len; - int realloc_size; + void *p = cp->hp; + int n = cp->len + len; + int realloc_size; /* * Optimization to avoid mmove. If there's enough space in front of @@ -1146,13 +1186,14 @@ int pool_unread(POOL_CONNECTION *cp, void *data, int len) if (cp->bufsz < n) { - realloc_size = (n/READBUFSZ+1)*READBUFSZ; + realloc_size = (n / READBUFSZ + 1) * READBUFSZ; + + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); p = repalloc(cp->hp, realloc_size); - MemoryContextSwitchTo(oldContext); - - cp->hp = p; + MemoryContextSwitchTo(oldContext); + + cp->hp = p; cp->bufsz = realloc_size; } if (cp->len != 0) @@ -1166,15 +1207,16 @@ int pool_unread(POOL_CONNECTION *cp, void *data, int len) /* * pool_push: Push data into buffer stack. */ -int pool_push(POOL_CONNECTION *cp, void *data, int len) +int +pool_push(POOL_CONNECTION * cp, void *data, int len) { - char *p; + char *p; ereport(DEBUG5, - (errmsg("pushing data of len: %d", len))); + (errmsg("pushing data of len: %d", len))); - MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); + MemoryContext oldContext = SwitchToConnectionContext(cp->isbackend); if (cp->bufsz3 == 0) { @@ -1189,7 +1231,7 @@ int pool_push(POOL_CONNECTION *cp, void *data, int len) memcpy(p, data, len); cp->bufsz3 += len; - MemoryContextSwitchTo(oldContext); + MemoryContextSwitchTo(oldContext); return 0; } @@ -1197,7 +1239,8 @@ int pool_push(POOL_CONNECTION *cp, void *data, int len) * pool_pop: Pop data from buffer stack and put back data using * pool_unread. */ -void pool_pop(POOL_CONNECTION *cp, int *len) +void +pool_pop(POOL_CONNECTION * cp, int *len) { if (cp->bufsz3 == 0) { @@ -1220,7 +1263,8 @@ void pool_pop(POOL_CONNECTION *cp, int *len) * pool_stacklen: Returns buffer stack length * pool_unread. */ -int pool_stacklen(POOL_CONNECTION *cp) +int +pool_stacklen(POOL_CONNECTION * cp) { return cp->bufsz3; } @@ -1228,47 +1272,49 @@ int pool_stacklen(POOL_CONNECTION *cp) /* * set non-block flag */ -void pool_set_nonblock(int fd) +void +pool_set_nonblock(int fd) { - int var; + int var; /* set fd to none blocking */ var = fcntl(fd, F_GETFL, 0); if (var == -1) { - ereport(FATAL, - (errmsg("unable to set options on socket"), - errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("unable to set options on socket"), + errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); } if (fcntl(fd, F_SETFL, var | O_NONBLOCK) == -1) { - ereport(FATAL, - (errmsg("unable to set options on socket"), - errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("unable to set options on socket"), + errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); } } /* * unset non-block flag */ -void pool_unset_nonblock(int fd) +void +pool_unset_nonblock(int fd) { - int var; + int var; /* set fd to none blocking */ var = fcntl(fd, F_GETFL, 0); if (var == -1) { - ereport(FATAL, - (errmsg("unable to set options on socket"), - errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("unable to set options on socket"), + errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); } if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1) { - ereport(FATAL, - (errmsg("unable to set options on socket"), - errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); + ereport(FATAL, + (errmsg("unable to set options on socket"), + errdetail("fcntl system call failed with error \"%s\"", strerror(errno)))); } } @@ -1276,7 +1322,8 @@ void pool_unset_nonblock(int fd) /* * Debug aid */ -static void dump_buffer(char *buf, int len) +static void +dump_buffer(char *buf, int len) { while (--len) { @@ -1285,38 +1332,44 @@ static void dump_buffer(char *buf, int len) } } #endif -int socket_write(int fd, void* buf, size_t len) +int +socket_write(int fd, void *buf, size_t len) { - int bytes_send = 0; + int bytes_send = 0; + do { - int ret; + int ret; + ret = write(fd, buf + bytes_send, (len - bytes_send)); - if (ret <=0) + if (ret <= 0) { if (errno == EINTR || errno == EAGAIN) { ereport(DEBUG5, - (errmsg("write on socket failed with error :\"%s\"",strerror(errno)), + (errmsg("write on socket failed with error :\"%s\"", strerror(errno)), errdetail("retrying..."))); continue; } ereport(LOG, - (errmsg("write on socket failed with error :\"%s\"",strerror(errno)))); + (errmsg("write on socket failed with error :\"%s\"", strerror(errno)))); return -1; } bytes_send += ret; - }while (bytes_send < len); + } while (bytes_send < len); return bytes_send; } -int socket_read(int fd, void* buf, size_t len, int timeout) +int +socket_read(int fd, void *buf, size_t len, int timeout) { - int ret, read_len; + int ret, + read_len; + read_len = 0; struct timeval timeoutval; - fd_set readmask; - int fds; + fd_set readmask; + int fds; while (read_len < len) { @@ -1326,7 +1379,7 @@ int socket_read(int fd, void* buf, size_t len, int timeout) timeoutval.tv_sec = timeout; timeoutval.tv_usec = 0; - fds = select(fd+1, &readmask, NULL, NULL, timeout?&timeoutval:NULL); + fds = select(fd + 1, &readmask, NULL, NULL, timeout ? &timeoutval : NULL); if (fds == -1) { if (errno == EAGAIN || errno == EINTR) @@ -1341,26 +1394,26 @@ int socket_read(int fd, void* buf, size_t len, int timeout) return -2; } ret = read(fd, buf + read_len, (len - read_len)); - if(ret < 0) + if (ret < 0) { if (errno == EINTR || errno == EAGAIN) { ereport(DEBUG5, - (errmsg("read from socket failed with error :\"%s\"",strerror(errno)), + (errmsg("read from socket failed with error :\"%s\"", strerror(errno)), errdetail("retrying..."))); continue; } ereport(LOG, - (errmsg("read from socket failed with error :\"%s\"",strerror(errno)))); + (errmsg("read from socket failed with error :\"%s\"", strerror(errno)))); return -1; } - if(ret == 0) + if (ret == 0) { ereport(LOG, (errmsg("read from socket failed, remote end closed the connection"))); return 0; } - read_len +=ret; + read_len += ret; } return read_len; } diff --git a/src/utils/ps_status.c b/src/utils/ps_status.c index 454a0eeef..903384615 100644 --- a/src/utils/ps_status.c +++ b/src/utils/ps_status.c @@ -103,9 +103,9 @@ static const size_t ps_buffer_size = PS_BUFFER_SIZE; #else /* PS_USE_CLOBBER_ARGV */ static char *ps_buffer; /* will point to argv area */ static size_t ps_buffer_size; /* space determined at run time */ -#endif /* PS_USE_CLOBBER_ARGV */ +#endif /* PS_USE_CLOBBER_ARGV */ -static size_t ps_buffer_fixed_size; /* size of the constant prefix */ +static size_t ps_buffer_fixed_size; /* size of the constant prefix */ /* save the original argv[] location here */ static int save_argc; @@ -176,7 +176,7 @@ save_ps_display_args(int argc, char **argv) new_environ[i] = NULL; environ = new_environ; } -#endif /* PS_USE_CLOBBER_ARGV */ +#endif /* PS_USE_CLOBBER_ARGV */ #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV) @@ -212,7 +212,7 @@ save_ps_display_args(int argc, char **argv) argv = new_argv; } -#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */ +#endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */ return argv; } @@ -242,7 +242,7 @@ init_ps_display(const char *username, const char *dbname, #ifdef PS_USE_CHANGE_ARGV save_argv[0] = ps_buffer; save_argv[1] = NULL; -#endif /* PS_USE_CHANGE_ARGV */ +#endif /* PS_USE_CHANGE_ARGV */ #ifdef PS_USE_CLOBBER_ARGV { @@ -252,7 +252,7 @@ init_ps_display(const char *username, const char *dbname, for (i = 1; i < save_argc; i++) save_argv[i] = ps_buffer + ps_buffer_size; } -#endif /* PS_USE_CLOBBER_ARGV */ +#endif /* PS_USE_CLOBBER_ARGV */ /* * Make fixed prefix of ps display. @@ -261,8 +261,8 @@ init_ps_display(const char *username, const char *dbname, #ifdef PS_USE_SETPROCTITLE /* - * apparently setproctitle() already adds a `progname: ' prefix to the - * ps line + * apparently setproctitle() already adds a `progname: ' prefix to the ps + * line */ snprintf(ps_buffer, ps_buffer_size, ""); #else @@ -273,7 +273,7 @@ init_ps_display(const char *username, const char *dbname, ps_buffer_fixed_size = strlen(ps_buffer); set_ps_display(initial_str, true); -#endif /* not PS_USE_NONE */ +#endif /* not PS_USE_NONE */ } @@ -314,12 +314,12 @@ set_ps_display(const char *activity, bool force) pst.pst_command = ps_buffer; pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); } -#endif /* PS_USE_PSTAT */ +#endif /* PS_USE_PSTAT */ #ifdef PS_USE_PS_STRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = ps_buffer; -#endif /* PS_USE_PS_STRINGS */ +#endif /* PS_USE_PS_STRINGS */ #ifdef PS_USE_CLOBBER_ARGV { @@ -329,7 +329,7 @@ set_ps_display(const char *activity, bool force) buflen = strlen(ps_buffer); memset(ps_buffer + buflen, PS_PADDING, ps_buffer_size - buflen); } -#endif /* PS_USE_CLOBBER_ARGV */ +#endif /* PS_USE_CLOBBER_ARGV */ #ifdef PS_USE_WIN32 { @@ -348,9 +348,9 @@ set_ps_display(const char *activity, bool force) ident_handle = CreateEvent(NULL, TRUE, FALSE, name); } -#endif /* PS_USE_WIN32 */ +#endif /* PS_USE_WIN32 */ -#endif /* not PS_USE_NONE */ +#endif /* not PS_USE_NONE */ } @@ -389,10 +389,11 @@ get_ps_display(int *displen) /* * Show ps idle status */ -void pool_ps_idle_display(POOL_CONNECTION_POOL *backend) +void +pool_ps_idle_display(POOL_CONNECTION_POOL * backend) { StartupPacket *sp; - char psbuf[1024]; + char psbuf[1024]; sp = MASTER_CONNECTION(backend)->sp; if (MASTER(backend)->tstate == 'T') diff --git a/src/utils/psprintf.c b/src/utils/psprintf.c index 3139f9716..430b044f5 100644 --- a/src/utils/psprintf.c +++ b/src/utils/psprintf.c @@ -28,7 +28,7 @@ #include "utils/fe_ports.h" /* It's possible we could use a different value for this in frontend code */ -#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ +#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ #endif diff --git a/src/utils/regex_array.c b/src/utils/regex_array.c index f85c16896..3f6c2297f 100644 --- a/src/utils/regex_array.c +++ b/src/utils/regex_array.c @@ -38,14 +38,15 @@ /* * Create RegArray object */ -RegArray *create_regex_array(void) +RegArray * +create_regex_array(void) { - RegArray *ar; + RegArray *ar; ar = palloc(sizeof(RegArray)); ar->pos = 0; ar->size = AR_ALLOC_UNIT; - ar->regex = (regex_t **)palloc(sizeof(regex_t *) * ar->size); + ar->regex = (regex_t **) palloc(sizeof(regex_t *) * ar->size); return ar; } @@ -53,12 +54,13 @@ RegArray *create_regex_array(void) /* * Add an regular expression pattern */ -int add_regex_array(RegArray *ar, char *pattern) +int +add_regex_array(RegArray * ar, char *pattern) { - int regex_flags; - regex_t *regex; - char *pat; - int len; + int regex_flags; + regex_t *regex; + char *pat; + int len; if (ar == NULL) { @@ -84,7 +86,7 @@ int add_regex_array(RegArray *ar, char *pattern) /* Add extended regex search */ regex_flags |= REG_EXTENDED; - pat = palloc(sizeof(char)*(len+3)); + pat = palloc(sizeof(char) * (len + 3)); if (strncmp(pattern, "^", 1) != 0) { strncpy(pat, "^", 2); @@ -126,9 +128,10 @@ int add_regex_array(RegArray *ar, char *pattern) /* * Execute regex matching. Returns matched array index. */ -int regex_array_match(RegArray *ar, char *pattern) +int +regex_array_match(RegArray * ar, char *pattern) { - int i; + int i; if (ar == NULL) { @@ -144,7 +147,7 @@ int regex_array_match(RegArray *ar, char *pattern) return -1; } - for (i=0;i<ar->pos;i++) + for (i = 0; i < ar->pos; i++) { if (regexec(ar->regex[i], pattern, 0, 0, 0) == 0) return i; @@ -155,7 +158,8 @@ int regex_array_match(RegArray *ar, char *pattern) /* * Destroy RegArray object */ -void destroy_regex_arrary(RegArray *ar) +void +destroy_regex_arrary(RegArray * ar) { pfree(ar->regex); pfree(ar); @@ -164,14 +168,15 @@ void destroy_regex_arrary(RegArray *ar) /* * Create L-R token array */ -Left_right_tokens *create_lrtoken_array(void) +Left_right_tokens * +create_lrtoken_array(void) { Left_right_tokens *ar; ar = palloc(sizeof(Left_right_tokens)); ar->pos = 0; ar->size = AR_ALLOC_UNIT; - ar->token = (Left_right_token *)palloc(sizeof(Left_right_token) * ar->size); + ar->token = (Left_right_token *) palloc(sizeof(Left_right_token) * ar->size); return ar; } @@ -181,32 +186,34 @@ Left_right_tokens *create_lrtoken_array(void) * and token lists are returned to left_tokens and right_tokens respectively. * Nnumber of tokens is set to *n. */ -void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_tokens *lrtokens) +void +extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_tokens * lrtokens) { - char *token; - char *mystr; + char *token; + char *mystr; mystr = pstrdup(str); for (token = strtok(mystr, delimi); token != NULL; token = strtok(NULL, delimi)) { - int len; - char *left_token; - char *right_token; - char *weight_token = NULL; - int i,j; - - len = strlen(token)+1; + int len; + char *left_token; + char *right_token; + char *weight_token = NULL; + int i, + j; + + len = strlen(token) + 1; left_token = palloc(len); right_token = palloc(len); weight_token = palloc(len); - for (i=0;token[i] && token[i] != delimi2;i++) + for (i = 0; token[i] && token[i] != delimi2; i++) left_token[i] = token[i]; left_token[i] = '\0'; - if (i == len -1) + if (i == len - 1) { pfree(left_token); pfree(right_token); @@ -218,17 +225,18 @@ void extract_string_tokens2(char *str, char *delimi, char delimi2, Left_right_to i++; j = 0; - for (;token[i] && token[i] != '('; i++) + for (; token[i] && token[i] != '('; i++) right_token[j++] = token[i]; right_token[j] = '\0'; /* delimiter 3 */ - int k = 0; + int k = 0; + if (token[i] == '(') { i++; - for (;token[i] && token[i] != ')'; i++) + for (; token[i] && token[i] != ')'; i++) weight_token[k++] = token[i]; } weight_token[k] = '\0'; diff --git a/src/utils/ssl_utils.c b/src/utils/ssl_utils.c index df3565528..eff2dde95 100644 --- a/src/utils/ssl_utils.c +++ b/src/utils/ssl_utils.c @@ -40,20 +40,22 @@ #include "utils/ssl_utils.h" #ifdef USE_SSL -static int aes_get_key(const char *password, unsigned char *key, unsigned char *iv); +static int aes_get_key(const char *password, unsigned char *key, unsigned char *iv); static int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, - unsigned char *iv, unsigned char *ciphertext); + unsigned char *iv, unsigned char *ciphertext); static int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, - unsigned char *iv, unsigned char *plaintext); + unsigned char *iv, unsigned char *plaintext); #endif #ifdef USE_SSL -int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, +int +aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, const char *password, unsigned char *ciphertext) { - unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + unsigned char key[EVP_MAX_KEY_LENGTH], + iv[EVP_MAX_IV_LENGTH]; /* First get the key and iv using the password */ if (aes_get_key(password, key, iv) != 0) @@ -61,10 +63,12 @@ int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, return aes_encrypt(plaintext, plaintext_len, key, iv, ciphertext); } -int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, - const char *password, unsigned char *plaintext) +int +aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, + const char *password, unsigned char *plaintext) { - unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + unsigned char key[EVP_MAX_KEY_LENGTH], + iv[EVP_MAX_IV_LENGTH]; /* First get the key and iv using the password */ if (aes_get_key(password, key, iv) != 0) @@ -77,15 +81,16 @@ int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, * key must be EVP_MAX_KEY_LENGTH length * iv must be EVP_MAX_IV_LENGTH length */ -static int aes_get_key(const char *password, unsigned char *key, unsigned char *iv) +static int +aes_get_key(const char *password, unsigned char *key, unsigned char *iv) { const unsigned char *salt = NULL; OpenSSL_add_all_algorithms(); - if(!EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, - (unsigned char *) password, - strlen(password), 1, key, iv)) + if (!EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha1(), salt, + (unsigned char *) password, + strlen(password), 1, key, iv)) { ereport(ERROR, (errmsg("unable to generate AES key from password"), @@ -94,8 +99,16 @@ static int aes_get_key(const char *password, unsigned char *key, unsigned char * } #ifdef DEBUG_ENCRYPT - printf("Key: "); for(i=0; i<EVP_aes_256_cbc()->key_len; ++i) { printf("%02x", key[i]); } printf("\n"); - printf("IV: "); for(i=0; i<EVP_aes_256_cbc()->iv_len; ++i) { printf("%02x", iv[i]); } printf("\n"); + printf("Key: "); + for (i = 0; i < EVP_aes_256_cbc()->key_len; ++i) + { + printf("%02x", key[i]); + } printf("\n"); + printf("IV: "); + for (i = 0; i < EVP_aes_256_cbc()->iv_len; ++i) + { + printf("%02x", iv[i]); + } printf("\n"); #endif return 0; } @@ -103,32 +116,37 @@ static int aes_get_key(const char *password, unsigned char *key, unsigned char * /* * from: https://wiki.openssl.org/index.php/EVP_Symmetric_Encryption_and_Decryption */ -static int aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, +static int +aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) { EVP_CIPHER_CTX *ctx = NULL; - int len; - int ciphertext_len; + int len; + int ciphertext_len; /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) + if (!(ctx = EVP_CIPHER_CTX_new())) goto encrypt_error; - /* Initialise the encryption operation. IMPORTANT - ensure you use a key - * and IV size appropriate for your cipher - * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * IV size for *most* modes is the same as the block size. For AES this - * is 128 bits */ + + /* + * Initialise the encryption operation. IMPORTANT - ensure you use a key + * and IV size appropriate for your cipher In this example we are using + * 256 bit AES (i.e. a 256 bit key). The IV size for *most* modes is the + * same as the block size. For AES this is 128 bits + */ if (EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1) goto encrypt_error; - /* Provide the message to be encrypted, and obtain the encrypted output. + /* + * Provide the message to be encrypted, and obtain the encrypted output. * EVP_EncryptUpdate can be called multiple times if necessary */ if (EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, plaintext_len) != 1) goto encrypt_error; ciphertext_len = len; - /* Finalise the encryption. Further ciphertext bytes may be written at + /* + * Finalise the encryption. Further ciphertext bytes may be written at * this stage. */ if (EVP_EncryptFinal_ex(ctx, ciphertext + len, &len) != 1) @@ -146,34 +164,38 @@ encrypt_error: return -1; } -static int aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, +static int +aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) { EVP_CIPHER_CTX *ctx = NULL; - int len; - int plaintext_len; + int len; + int plaintext_len; /* Create and initialise the context */ - if(!(ctx = EVP_CIPHER_CTX_new())) + if (!(ctx = EVP_CIPHER_CTX_new())) goto decrypt_error; - /* Initialise the decryption operation. IMPORTANT - ensure you use a key - * and IV size appropriate for your cipher - * In this example we are using 256 bit AES (i.e. a 256 bit key). The - * IV size for *most* modes is the same as the block size. For AES this - * is 128 bits */ + /* + * Initialise the decryption operation. IMPORTANT - ensure you use a key + * and IV size appropriate for your cipher In this example we are using + * 256 bit AES (i.e. a 256 bit key). The IV size for *most* modes is the + * same as the block size. For AES this is 128 bits + */ if (EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv) != 1) goto decrypt_error; - /* Provide the message to be decrypted, and obtain the plaintext output. + /* + * Provide the message to be decrypted, and obtain the plaintext output. * EVP_DecryptUpdate can be called multiple times if necessary */ if (EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, ciphertext_len) != 1) goto decrypt_error; plaintext_len = len; - /* Finalise the decryption. Further plaintext bytes may be written at - * this stage. + /* + * Finalise the decryption. Further plaintext bytes may be written at this + * stage. */ if (EVP_DecryptFinal_ex(ctx, plaintext + len, &len) != 1) goto decrypt_error; @@ -191,58 +213,61 @@ decrypt_error: } /* HMAC SHA-256*/ -void calculate_hmac_sha256(const char *data, int len, char *buf) +void +calculate_hmac_sha256(const char *data, int len, char *buf) { - char* key = pool_config->wd_authkey; - char str[WD_AUTH_HASH_LEN/2]; + char *key = pool_config->wd_authkey; + char str[WD_AUTH_HASH_LEN / 2]; unsigned int res_len = WD_AUTH_HASH_LEN; - HMAC_CTX *ctx = NULL; + HMAC_CTX *ctx = NULL; #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined (LIBRESSL_VERSION_NUMBER)) ctx = HMAC_CTX_new(); HMAC_CTX_reset(ctx); #else - HMAC_CTX ctx_obj; + HMAC_CTX ctx_obj; + ctx = &ctx_obj; HMAC_CTX_init(ctx); #endif HMAC_Init_ex(ctx, key, strlen(key), EVP_sha256(), NULL); - HMAC_Update(ctx, (unsigned char*)data, len); - HMAC_Final(ctx, (unsigned char*)str, &res_len); + HMAC_Update(ctx, (unsigned char *) data, len); + HMAC_Final(ctx, (unsigned char *) str, &res_len); #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined (LIBRESSL_VERSION_NUMBER)) HMAC_CTX_reset(ctx); HMAC_CTX_free(ctx); #else HMAC_CTX_cleanup(ctx); #endif - bytesToHex(str,32,buf); + bytesToHex(str, 32, buf); buf[WD_AUTH_HASH_LEN] = '\0'; } #else -int aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, - const char *password, unsigned char *plaintext) +int +aes_decrypt_with_password(unsigned char *ciphertext, int ciphertext_len, + const char *password, unsigned char *plaintext) { ereport(ERROR, - (errmsg("AES decryption is not supported by this build"), + (errmsg("AES decryption is not supported by this build"), errhint("Compile with --with-openssl to use AES."))); return -1; } -int aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, - const char *password, unsigned char *ciphertext) +int +aes_encrypt_with_password(unsigned char *plaintext, int plaintext_len, + const char *password, unsigned char *ciphertext) { ereport(ERROR, - (errmsg("AES encryption is not supported by this build"), + (errmsg("AES encryption is not supported by this build"), errhint("Compile with --with-openssl to use AES."))); return -1; } -void calculate_hmac_sha256(const char *data, int len, char *buf) +void +calculate_hmac_sha256(const char *data, int len, char *buf) { ereport(ERROR, (errmsg("HMAC SHA256 encryption is not supported by this build"), errhint("Compile with --with-openssl to use AES."))); } #endif - - diff --git a/src/utils/statistics.c b/src/utils/statistics.c index 63684de83..940de5b2e 100644 --- a/src/utils/statistics.c +++ b/src/utils/statistics.c @@ -25,23 +25,25 @@ /* * Per backend node stat area in shared memory */ -typedef struct { - uint64 select_cnt; /* number of read SELECT queries issued */ - uint64 insert_cnt; /* number of INSERT queries issued */ - uint64 update_cnt; /* number of UPDATE queries issued */ - uint64 delete_cnt; /* number of DELETE queries issued */ - uint64 ddl_cnt; /* number of DDL queries issued */ - uint64 other_cnt; /* number of any other queries issued */ -} PER_NODE_STAT; +typedef struct +{ + uint64 select_cnt; /* number of read SELECT queries issued */ + uint64 insert_cnt; /* number of INSERT queries issued */ + uint64 update_cnt; /* number of UPDATE queries issued */ + uint64 delete_cnt; /* number of DELETE queries issued */ + uint64 ddl_cnt; /* number of DDL queries issued */ + uint64 other_cnt; /* number of any other queries issued */ +} PER_NODE_STAT; static volatile PER_NODE_STAT *per_node_stat; /* * Return shared memory size necessary for this module */ -size_t stat_shared_memory_size(void) +size_t +stat_shared_memory_size(void) { - size_t size; + size_t size; /* query counter area */ size = MAXALIGN(MAX_NUM_BACKENDS * sizeof(PER_NODE_STAT)); @@ -53,23 +55,26 @@ size_t stat_shared_memory_size(void) * Set PER_NODE_STAT address in the shared memory area to global variable. * This should be called from pgpool main process upon startup. */ -void stat_set_stat_area(void *address) +void +stat_set_stat_area(void *address) { - per_node_stat = (PER_NODE_STAT *)address; + per_node_stat = (PER_NODE_STAT *) address; } /* * Initialize shared memory stat area */ -void stat_init_stat_area(void) +void +stat_init_stat_area(void) { - memset((void *)per_node_stat, 0, stat_shared_memory_size()); + memset((void *) per_node_stat, 0, stat_shared_memory_size()); } -/* +/* * Update stat counter */ -void stat_count_up(int backend_node_id, Node *parse_tree) +void +stat_count_up(int backend_node_id, Node *parse_tree) { if (parse_tree == NULL) { @@ -91,7 +96,8 @@ void stat_count_up(int backend_node_id, Node *parse_tree) /* * Stat counter read functions */ -uint64 stat_get_select_count(int backend_node_id) +uint64 +stat_get_select_count(int backend_node_id) { return per_node_stat[backend_node_id].select_cnt; } diff --git a/src/watchdog/test/stab.c b/src/watchdog/test/stab.c index 4ea39704c..da66a5bc5 100644 --- a/src/watchdog/test/stab.c +++ b/src/watchdog/test/stab.c @@ -11,44 +11,48 @@ #define MAXSTRFTIME 128 -int debug = 0; +int debug = 0; static char *nowsec(void); static void child_wait(int signo); -void pool_error(const char *fmt,...) +void +pool_error(const char *fmt,...) { va_list ap; pool_sigset_t oldmask; #ifdef HAVE_ASPRINTF - char *fmt2; - int len; + char *fmt2; + int len; #endif /* Write error message to syslog */ - if (pool_config->logsyslog == 1) { - va_start(ap, fmt); - vsyslog(pool_config->syslog_facility | LOG_ERR, fmt, ap); - va_end(ap); - return; + if (pool_config->logsyslog == 1) + { + va_start(ap, fmt); + vsyslog(pool_config->syslog_facility | LOG_ERR, fmt, ap); + va_end(ap); + return; } POOL_SETMASK2(&BlockSig, &oldmask); - /*TODO - if (pool_config->print_timestamp)*/ + + /* + * TODO if (pool_config->print_timestamp) + */ #ifdef HAVE_ASPRINTF - len = asprintf(&fmt2, "%s ERROR: pid %d: %s\n", nowsec(), (int)getpid(), fmt); - - if (len >= 0 && fmt2) - { - va_start(ap, fmt); - vfprintf(stderr, fmt2, ap); - va_end(ap); - fflush(stderr); - free(fmt2); - } + len = asprintf(&fmt2, "%s ERROR: pid %d: %s\n", nowsec(), (int) getpid(), fmt); + + if (len >= 0 && fmt2) + { + va_start(ap, fmt); + vfprintf(stderr, fmt2, ap); + va_end(ap); + fflush(stderr); + free(fmt2); + } #else - fprintf(stderr, "%s ERROR: pid %d: ", nowsec(), (int)getpid()); + fprintf(stderr, "%s ERROR: pid %d: ", nowsec(), (int) getpid()); va_start(ap, fmt); vfprintf(stderr, fmt, ap); @@ -59,10 +63,11 @@ void pool_error(const char *fmt,...) POOL_SETMASK(&oldmask); } -static char *nowsec(void) +static char * +nowsec(void) { static char strbuf[MAXSTRFTIME]; - time_t now = time(NULL); + time_t now = time(NULL); strftime(strbuf, MAXSTRFTIME, "%Y-%m-%d %H:%M:%S", localtime(&now)); return strbuf; @@ -100,18 +105,20 @@ strlcpy(char *dst, const char *src, size_t siz) static void child_wait(int signo) { - pid_t pid = 0; + pid_t pid = 0; + + do + { + int ret; - do { - int ret; - pid = waitpid(-1,&ret,WNOHANG); - } while(pid > 0); + pid = waitpid(-1, &ret, WNOHANG); + } while (pid > 0); } void wd_exit(int exit_signo) { - sigset_t mask; + sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGTERM); @@ -124,14 +131,15 @@ wd_exit(int exit_signo) pool_shmem_exit(1); - kill (0, exit_signo); + kill(0, exit_signo); child_wait(0); exit(0); } -int pool_memset_system_db_info (SystemDBInfo *info) +int +pool_memset_system_db_info(SystemDBInfo * info) { return 0; } @@ -141,4 +149,3 @@ pool_query_cache_table_exists(void) { return 0; } - diff --git a/src/watchdog/test/test.c b/src/watchdog/test/test.c index 56440be43..26b7ed32f 100644 --- a/src/watchdog/test/test.c +++ b/src/watchdog/test/test.c @@ -10,22 +10,22 @@ #include "watchdog.h" #include "wd_ext.h" -pid_t mypid; +pid_t mypid; static void wdlist_dump(void); extern void wd_exit(int exit_signo); int -main(int argc, char * argv[]) +main(int argc, char *argv[]) { - int rtn; + int rtn; signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_IGN); - signal(SIGINT, wd_exit); - signal(SIGQUIT, wd_exit); - signal(SIGTERM, wd_exit); - signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, wd_exit); + signal(SIGQUIT, wd_exit); + signal(SIGTERM, wd_exit); + signal(SIGPIPE, SIG_IGN); mypid = getpid(); rtn = pool_init_config(); @@ -37,11 +37,11 @@ main(int argc, char * argv[]) pool_config->port = 5432; pool_config->wd_port = 9999; pool_config->other_wd->num_wd = 2; - strcpy(pool_config->other_wd->wd_info[0].hostname ,"vm2"); + strcpy(pool_config->other_wd->wd_info[0].hostname, "vm2"); pool_config->other_wd->wd_info[0].pgpool_port = 5432; pool_config->other_wd->wd_info[0].wd_port = 9999; pool_config->other_wd->wd_info[0].status = WD_INIT; - strcpy(pool_config->other_wd->wd_info[1].hostname ,"paris"); + strcpy(pool_config->other_wd->wd_info[1].hostname, "paris"); pool_config->other_wd->wd_info[1].pgpool_port = 5432; pool_config->other_wd->wd_info[1].wd_port = 9999; pool_config->other_wd->wd_info[1].status = WD_INIT; @@ -51,7 +51,7 @@ main(int argc, char * argv[]) pool_config->if_down_cmd = "ifconfig eth0:0 down"; pool_config->wd_interval = 3; pool_config->wd_life_point = 1; - + wd_main(3); for (;;) @@ -67,18 +67,18 @@ main(int argc, char * argv[]) static void wdlist_dump(void) { - int i; - WdInfo * p = WD_List; + int i; + WdInfo *p = WD_List; i = 0; while (p->status != WD_END) { printf("%d:s[%d] ts[%d] tu[%d] h[%s] pp[%d] wp[%d]\n", - i,p->status, - p->tv.tv_sec, p->tv.tv_usec, - p->hostname, - p->pgpool_port, - p->wd_port); + i, p->status, + p->tv.tv_sec, p->tv.tv_usec, + p->hostname, + p->pgpool_port, + p->wd_port); p++; i++; } diff --git a/src/watchdog/test/wd_child_t.c b/src/watchdog/test/wd_child_t.c index b9e69e847..a469ca7ab 100644 --- a/src/watchdog/test/wd_child_t.c +++ b/src/watchdog/test/wd_child_t.c @@ -10,23 +10,23 @@ #include "watchdog.h" #include "wd_ext.h" -pid_t mypid; -WdInfo * WD_List = NULL; /* watchdog server list */ +pid_t mypid; +WdInfo *WD_List = NULL; /* watchdog server list */ static void wdlist_dump(void); extern void wd_exit(int exit_signo); int -main(int argc, char * argv[]) +main(int argc, char *argv[]) { - int rtn; + int rtn; signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_IGN); - signal(SIGINT, wd_exit); - signal(SIGQUIT, wd_exit); - signal(SIGTERM, wd_exit); - signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, wd_exit); + signal(SIGQUIT, wd_exit); + signal(SIGTERM, wd_exit); + signal(SIGPIPE, SIG_IGN); mypid = getpid(); rtn = pool_init_config(); @@ -38,11 +38,11 @@ main(int argc, char * argv[]) pool_config->port = 5432; pool_config->wd_port = 9999; pool_config->other_wd->num_wd = 2; - strcpy(pool_config->other_wd->wd_info[0].hostname ,"vm2"); + strcpy(pool_config->other_wd->wd_info[0].hostname, "vm2"); pool_config->other_wd->wd_info[0].pgpool_port = 5432; pool_config->other_wd->wd_info[0].wd_port = 9999; pool_config->other_wd->wd_info[0].status = WD_INIT; - strcpy(pool_config->other_wd->wd_info[1].hostname ,"paris"); + strcpy(pool_config->other_wd->wd_info[1].hostname, "paris"); pool_config->other_wd->wd_info[1].pgpool_port = 5432; pool_config->other_wd->wd_info[1].wd_port = 9999; pool_config->other_wd->wd_info[1].status = WD_INIT; @@ -52,16 +52,16 @@ main(int argc, char * argv[]) pool_config->if_down_cmd = "ifconfig eth0:0 down"; pool_config->wd_interval = 3; pool_config->wd_life_point = 1; - + wd_init(); - + wd_child(1); for (;;) { wdlist_dump(); sleep(5); - } + } } @@ -69,18 +69,18 @@ main(int argc, char * argv[]) static void wdlist_dump(void) { - int i; - WdInfo * p = WD_List; + int i; + WdInfo *p = WD_List; i = 0; while (p->status != WD_END) { printf("%d:s[%d] ts[%d] tu[%d] h[%s] pp[%d] wp[%d]\n", - i,p->status, - p->tv.tv_sec, p->tv.tv_usec, - p->hostname, - p->pgpool_port, - p->wd_port); + i, p->status, + p->tv.tv_sec, p->tv.tv_usec, + p->hostname, + p->pgpool_port, + p->wd_port); p++; i++; } diff --git a/src/watchdog/test/wd_lifecheck_t.c b/src/watchdog/test/wd_lifecheck_t.c index e1628287d..4fd5ffdeb 100644 --- a/src/watchdog/test/wd_lifecheck_t.c +++ b/src/watchdog/test/wd_lifecheck_t.c @@ -10,23 +10,23 @@ #include "watchdog.h" #include "wd_ext.h" -pid_t mypid; -WdInfo * WD_List = NULL; /* watchdog server list */ +pid_t mypid; +WdInfo *WD_List = NULL; /* watchdog server list */ static void wdlist_dump(void); extern void wd_exit(int exit_signo); int -main(int argc, char * argv[]) +main(int argc, char *argv[]) { - int rtn; + int rtn; signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_IGN); - signal(SIGINT, wd_exit); - signal(SIGQUIT, wd_exit); - signal(SIGTERM, wd_exit); - signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, wd_exit); + signal(SIGQUIT, wd_exit); + signal(SIGTERM, wd_exit); + signal(SIGPIPE, SIG_IGN); mypid = getpid(); rtn = pool_init_config(); @@ -38,11 +38,11 @@ main(int argc, char * argv[]) pool_config->port = 5432; pool_config->wd_port = 9999; pool_config->other_wd->num_wd = 2; - strcpy(pool_config->other_wd->wd_info[0].hostname ,"vm2"); + strcpy(pool_config->other_wd->wd_info[0].hostname, "vm2"); pool_config->other_wd->wd_info[0].pgpool_port = 5432; pool_config->other_wd->wd_info[0].wd_port = 9999; pool_config->other_wd->wd_info[0].status = WD_INIT; - strcpy(pool_config->other_wd->wd_info[1].hostname ,"paris"); + strcpy(pool_config->other_wd->wd_info[1].hostname, "paris"); pool_config->other_wd->wd_info[1].pgpool_port = 5432; pool_config->other_wd->wd_info[1].wd_port = 9999; pool_config->other_wd->wd_info[1].status = WD_INIT; @@ -52,7 +52,7 @@ main(int argc, char * argv[]) pool_config->if_down_cmd = "ifconfig eth0:0 down"; pool_config->wd_interval = 3; pool_config->wd_life_point = 1; - + wd_init(); for (;;) @@ -69,18 +69,18 @@ main(int argc, char * argv[]) static void wdlist_dump(void) { - int i; - WdInfo * p = WD_List; + int i; + WdInfo *p = WD_List; i = 0; while (p->status != WD_END) { printf("%d:s[%d] ts[%d] tu[%d] h[%s] pp[%d] wp[%d]\n", - i,p->status, - p->tv.tv_sec, p->tv.tv_usec, - p->hostname, - p->pgpool_port, - p->wd_port); + i, p->status, + p->tv.tv_sec, p->tv.tv_usec, + p->hostname, + p->pgpool_port, + p->wd_port); p++; i++; } diff --git a/src/watchdog/test/wd_packet_t.c b/src/watchdog/test/wd_packet_t.c index 0740a117e..7b6b90935 100644 --- a/src/watchdog/test/wd_packet_t.c +++ b/src/watchdog/test/wd_packet_t.c @@ -10,23 +10,23 @@ #include "watchdog.h" #include "wd_ext.h" -pid_t mypid; -WdInfo * WD_List = NULL; /* watchdog server list */ +pid_t mypid; +WdInfo *WD_List = NULL; /* watchdog server list */ static void wdlist_dump(void); extern void wd_exit(int exit_signo); int -main(int argc, char * argv[]) +main(int argc, char *argv[]) { - int rtn; + int rtn; signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_IGN); - signal(SIGINT, wd_exit); - signal(SIGQUIT, wd_exit); - signal(SIGTERM, wd_exit); - signal(SIGPIPE, SIG_IGN); + signal(SIGHUP, SIG_IGN); + signal(SIGINT, wd_exit); + signal(SIGQUIT, wd_exit); + signal(SIGTERM, wd_exit); + signal(SIGPIPE, SIG_IGN); mypid = getpid(); rtn = pool_init_config(); @@ -38,11 +38,11 @@ main(int argc, char * argv[]) pool_config->port = 5432; pool_config->wd_port = 9999; pool_config->other_wd->num_wd = 2; - strcpy(pool_config->other_wd->wd_info[0].hostname ,"vm2"); + strcpy(pool_config->other_wd->wd_info[0].hostname, "vm2"); pool_config->other_wd->wd_info[0].pgpool_port = 5432; pool_config->other_wd->wd_info[0].wd_port = 9999; pool_config->other_wd->wd_info[0].status = WD_INIT; - strcpy(pool_config->other_wd->wd_info[1].hostname ,"paris"); + strcpy(pool_config->other_wd->wd_info[1].hostname, "paris"); pool_config->other_wd->wd_info[1].pgpool_port = 5432; pool_config->other_wd->wd_info[1].wd_port = 9999; pool_config->other_wd->wd_info[1].status = WD_INIT; @@ -52,7 +52,7 @@ main(int argc, char * argv[]) pool_config->if_down_cmd = "ifconfig eth0:0 down"; pool_config->wd_interval = 3; pool_config->wd_life_point = 1; - + wd_init(); for (;;) @@ -69,18 +69,18 @@ main(int argc, char * argv[]) static void wdlist_dump(void) { - int i; - WdInfo * p = WD_List; + int i; + WdInfo *p = WD_List; i = 0; while (p->status != WD_END) { printf("%d:s[%d] ts[%d] tu[%d] h[%s] pp[%d] wp[%d]\n", - i,p->status, - p->tv.tv_sec, p->tv.tv_usec, - p->hostname, - p->pgpool_port, - p->wd_port); + i, p->status, + p->tv.tv_sec, p->tv.tv_usec, + p->hostname, + p->pgpool_port, + p->wd_port); p++; i++; } diff --git a/src/watchdog/test/wd_ping_t.c b/src/watchdog/test/wd_ping_t.c index 0b90178f9..366a272f1 100644 --- a/src/watchdog/test/wd_ping_t.c +++ b/src/watchdog/test/wd_ping_t.c @@ -1,20 +1,21 @@ #include <stdio.h> #include "watchdog.h" -extern int wd_is_upper_ok(char * server_list); +extern int wd_is_upper_ok(char *server_list); int -main(int argc,char * argv[]) +main(int argc, char *argv[]) { - int rtn; + int rtn; + rtn = wd_is_upper_ok(argv[1]); if (rtn == WD_OK) { - printf("%s is ok",argv[1]); + printf("%s is ok", argv[1]); } else { - printf("%s is ng",argv[1]); + printf("%s is ng", argv[1]); } return 0; } diff --git a/src/watchdog/watchdog.c b/src/watchdog/watchdog.c index 4ee6ee51a..16f940b76 100644 --- a/src/watchdog/watchdog.c +++ b/src/watchdog/watchdog.c @@ -73,26 +73,25 @@ typedef enum IPC_CMD_PREOCESS_RES IPC_CMD_ERROR, IPC_CMD_OK, IPC_CMD_TRY_AGAIN -}IPC_CMD_PREOCESS_RES; +} IPC_CMD_PREOCESS_RES; -#define MIN_SECS_CONNECTION_RETRY 10 /* Time in seconds to - * retry connection with - * node once it was failed */ +#define MIN_SECS_CONNECTION_RETRY 10 /* Time in seconds to retry connection + * with node once it was failed */ -#define MAX_SECS_ESC_PROC_EXIT_WAIT 5 /* maximum amount of seconds to - * wait for escalation/de-esclation process to - * exit normaly before moving on - */ +#define MAX_SECS_ESC_PROC_EXIT_WAIT 5 /* maximum amount of seconds to wait + * for escalation/de-esclation process + * to exit normaly before moving on */ -#define BEACON_MESSAGE_INTERVAL_SECONDS 10 /* interval between beacon messages */ +#define BEACON_MESSAGE_INTERVAL_SECONDS 10 /* interval between beacon + * messages */ -#define MAX_SECS_WAIT_FOR_REPLY_FROM_NODE 5 /* time in seconds to wait for the reply from - * remote watchdog node - */ -#define FAILOVER_COMMAND_FINISH_TIMEOUT 15 /* timeout in seconds to wait for Pgpool-II to - * build consensus for failover - */ +#define MAX_SECS_WAIT_FOR_REPLY_FROM_NODE 5 /* time in seconds to wait for + * the reply from remote + * watchdog node */ +#define FAILOVER_COMMAND_FINISH_TIMEOUT 15 /* timeout in seconds to wait + * for Pgpool-II to build + * consensus for failover */ #define WD_NO_MESSAGE 0 @@ -134,9 +133,9 @@ typedef enum IPC_CMD_PREOCESS_RES typedef struct packet_types { - char type; - char name[100]; -}packet_types; + char type; + char name[100]; +} packet_types; packet_types all_packet_types[] = { {WD_ADD_NODE_MESSAGE, "ADD NODE"}, @@ -161,8 +160,8 @@ packet_types all_packet_types[] = { {WD_GET_MASTER_DATA_REQUEST, "DATA REQUEST FOR MASTER"}, {WD_GET_RUNTIME_VARIABLE_VALUE, "GET WD RUNTIME VARIABLE VALUE"}, {WD_CMD_REPLY_IN_DATA, "COMMAND REPLY IN DATA"}, - {WD_FAILOVER_LOCKING_REQUEST,"FAILOVER LOCKING REQUEST"}, - {WD_FAILOVER_INDICATION,"FAILOVER INDICATION"}, + {WD_FAILOVER_LOCKING_REQUEST, "FAILOVER LOCKING REQUEST"}, + {WD_FAILOVER_INDICATION, "FAILOVER INDICATION"}, {WD_CLUSTER_SERVICE_MESSAGE, "CLUSTER SERVICE MESSAGE"}, {WD_REGISTER_FOR_NOTIFICATION, "REGISTER FOR NOTIFICATION"}, {WD_NODE_STATUS_CHANGE_COMMAND, "NODE STATUS CHANGE"}, @@ -171,19 +170,19 @@ packet_types all_packet_types[] = { {WD_IPC_CMD_RESULT_BAD, "IPC RESPONSE BAD"}, {WD_IPC_CMD_RESULT_OK, "IPC RESPONSE GOOD"}, {WD_IPC_CMD_TIMEOUT, "IPC TIMEOUT"}, - {WD_NO_MESSAGE,""} + {WD_NO_MESSAGE, ""} }; -char* wd_failover_lock_name[] = +char *wd_failover_lock_name[] = { "FAILOVER", "FAILBACK", "FOLLOW MASTER" }; -char *wd_event_name[] = -{ "STATE CHANGED", +char *wd_event_name[] = +{"STATE CHANGED", "TIMEOUT", "PACKET RECEIVED", "COMMAND FINISHED", @@ -201,7 +200,7 @@ char *wd_event_name[] = "CLUSTER QUORUM STATUS CHANGED" }; -char *wd_state_names[] = { +char *wd_state_names[] = { "DEAD", "LOADING", "JOINING", @@ -218,11 +217,11 @@ char *wd_state_names[] = { typedef struct WDPacketData { - char type; - int command_id; - int len; - char* data; -}WDPacketData; + char type; + int command_id; + int len; + char *data; +} WDPacketData; typedef enum WDNodeCommandState @@ -232,16 +231,16 @@ typedef enum WDNodeCommandState COMMAND_STATE_REPLIED, COMMAND_STATE_SEND_ERROR, COMMAND_STATE_DO_NOT_SEND -}WDNodeCommandState; +} WDNodeCommandState; typedef struct WDCommandNodeResult { - WatchdogNode* wdNode; + WatchdogNode *wdNode; WDNodeCommandState cmdState; - char result_type; - int result_data_len; - char* result_data; -}WDCommandNodeResult; + char result_type; + int result_data_len; + char *result_data; +} WDCommandNodeResult; typedef enum WDCommandSource { @@ -249,23 +248,23 @@ typedef enum WDCommandSource COMMAND_SOURCE_LOCAL, COMMAND_SOURCE_REMOTE, COMMAND_SOURCE_INTERNAL -}WDCommandSource; +} WDCommandSource; typedef struct WDFunctionCommandData { - char commandType; - unsigned int commandID; - char* funcName; - WatchdogNode* wdNode; -}WDFunctionCommandData; + char commandType; + unsigned int commandID; + char *funcName; + WatchdogNode *wdNode; +} WDFunctionCommandData; typedef struct WDCommandTimerData { - struct timeval startTime; - unsigned int expire_sec; - bool need_tics; - WDFunctionCommandData* wd_func_command; -}WDCommandTimerData; + struct timeval startTime; + unsigned int expire_sec; + bool need_tics; + WDFunctionCommandData *wd_func_command; +} WDCommandTimerData; typedef enum WDCommandStatus @@ -276,97 +275,97 @@ typedef enum WDCommandStatus COMMAND_FINISHED_ALL_REPLIED, COMMAND_FINISHED_NODE_REJECTED, COMMAND_FINISHED_SEND_FAILED -}WDCommandStatus; +} WDCommandStatus; typedef struct WDCommandData { - WDPacketData sourcePacket; - WDPacketData commandPacket; - WDCommandNodeResult *nodeResults; - WatchdogNode *sendToNode; /* NULL means send to all */ - WDCommandStatus commandStatus; - unsigned int commandTimeoutSecs; - struct timeval commandTime; - unsigned int commandSendToCount; - unsigned int commandSendToErrorCount; - unsigned int commandReplyFromCount; - WDCommandSource commandSource; - int sourceIPCSocket; /* Only valid for COMMAND_SOURCE_IPC */ - WatchdogNode *sourceWdNode; /* Only valid for COMMAND_SOURCE_REMOTE */ - char *errorMessage; - MemoryContext memoryContext; - void (*commandCompleteFunc)(struct WDCommandData* command); -}WDCommandData; + WDPacketData sourcePacket; + WDPacketData commandPacket; + WDCommandNodeResult *nodeResults; + WatchdogNode *sendToNode; /* NULL means send to all */ + WDCommandStatus commandStatus; + unsigned int commandTimeoutSecs; + struct timeval commandTime; + unsigned int commandSendToCount; + unsigned int commandSendToErrorCount; + unsigned int commandReplyFromCount; + WDCommandSource commandSource; + int sourceIPCSocket; /* Only valid for COMMAND_SOURCE_IPC */ + WatchdogNode *sourceWdNode; /* Only valid for COMMAND_SOURCE_REMOTE */ + char *errorMessage; + MemoryContext memoryContext; + void (*commandCompleteFunc) (struct WDCommandData *command); +} WDCommandData; typedef struct WDInterfaceStatus { - char* if_name; - unsigned int if_index; - bool if_up; -}WDInterfaceStatus; + char *if_name; + unsigned int if_index; + bool if_up; +} WDInterfaceStatus; typedef struct WDClusterMaster { - WatchdogNode* masterNode; - WatchdogNode** standbyNodes; - int standby_nodes_count; - bool holding_vip; -}WDClusterMasterInfo; + WatchdogNode *masterNode; + WatchdogNode **standbyNodes; + int standby_nodes_count; + bool holding_vip; +} WDClusterMasterInfo; typedef struct wd_cluster { - WatchdogNode* localNode; - WatchdogNode* remoteNodes; - WDClusterMasterInfo clusterMasterInfo; - int remoteNodeCount; - int quorum_status; - unsigned int nextCommandID; - pid_t escalation_pid; - pid_t de_escalation_pid; - int command_server_sock; - int network_monitor_sock; - bool clusterInitialized; - bool ipc_auth_needed; - int current_failover_id; - List *unidentified_socks; - List *notify_clients; - List *ipc_command_socks; - List *ipc_commands; - List *clusterCommands; - List *wd_timer_commands; - List *wdInterfaceToMonitor; - List *wdCurrentFailovers; -}wd_cluster; + WatchdogNode *localNode; + WatchdogNode *remoteNodes; + WDClusterMasterInfo clusterMasterInfo; + int remoteNodeCount; + int quorum_status; + unsigned int nextCommandID; + pid_t escalation_pid; + pid_t de_escalation_pid; + int command_server_sock; + int network_monitor_sock; + bool clusterInitialized; + bool ipc_auth_needed; + int current_failover_id; + List *unidentified_socks; + List *notify_clients; + List *ipc_command_socks; + List *ipc_commands; + List *clusterCommands; + List *wd_timer_commands; + List *wdInterfaceToMonitor; + List *wdCurrentFailovers; +} wd_cluster; typedef struct WDFailoverObject { - int id; + int id; POOL_REQUEST_KIND reqKind; unsigned char reqFlags; - int nodesCount; + int nodesCount; unsigned int failoverID; - int *nodeList; - List* requestingNodes; - int request_count; - struct timeval startTime; - int state; -}WDFailoverObject; + int *nodeList; + List *requestingNodes; + int request_count; + struct timeval startTime; + int state; +} WDFailoverObject; -static void process_remote_failover_command_on_coordinator(WatchdogNode* wdNode, WDPacketData* pkt); -static WDFailoverObject* get_failover_object(POOL_REQUEST_KIND reqKind, int nodesCount, int *nodeList); +static void process_remote_failover_command_on_coordinator(WatchdogNode * wdNode, WDPacketData * pkt); +static WDFailoverObject * get_failover_object(POOL_REQUEST_KIND reqKind, int nodesCount, int *nodeList); static bool does_int_array_contains_value(int *intArray, int count, int value); static void clear_all_failovers(void); -static void remove_failover_object(WDFailoverObject* failoverObj); +static void remove_failover_object(WDFailoverObject * failoverObj); static void service_expired_failovers(void); -static WDFailoverObject* add_failover(POOL_REQUEST_KIND reqKind, int *node_id_list, int node_count, WatchdogNode *wdNode, - unsigned char flags, bool *duplicate); -static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind,int *node_id_list, - int node_count, unsigned char *flags, WatchdogNode *wdNode); +static WDFailoverObject * add_failover(POOL_REQUEST_KIND reqKind, int *node_id_list, int node_count, WatchdogNode * wdNode, + unsigned char flags, bool *duplicate); +static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind, int *node_id_list, + int node_count, unsigned char *flags, WatchdogNode * wdNode); -static int send_command_packet_to_remote_nodes(WDCommandData* ipcCommand, bool source_included); -static void wd_command_is_complete(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES wd_command_processor_for_node_lost_event(WDCommandData* ipcCommand, WatchdogNode* wdLostNode); +static int send_command_packet_to_remote_nodes(WDCommandData * ipcCommand, bool source_included); +static void wd_command_is_complete(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES wd_command_processor_for_node_lost_event(WDCommandData * ipcCommand, WatchdogNode * wdLostNode); volatile sig_atomic_t reload_config_signal = 0; volatile sig_atomic_t sigchld_request = 0; @@ -379,173 +378,176 @@ static void wd_child_exit(int exit_signo); static void wd_cluster_initialize(void); static void wd_initialize_monitoring_interfaces(void); -static int wd_create_client_socket(char * hostname, int port, bool *connected); -static int connect_with_all_configured_nodes(void); +static int wd_create_client_socket(char *hostname, int port, bool *connected); +static int connect_with_all_configured_nodes(void); static void try_connecting_with_all_unreachable_nodes(void); -static bool connect_to_node(WatchdogNode* wdNode); -static bool is_socket_connection_connected(SocketConnection* conn); +static bool connect_to_node(WatchdogNode * wdNode); +static bool is_socket_connection_connected(SocketConnection * conn); static void service_unreachable_nodes(void); -static void allocate_resultNodes_in_command(WDCommandData* ipcCommand); -static bool is_node_active_and_reachable(WatchdogNode* wdNode); -static bool is_node_active(WatchdogNode* wdNode); -static bool is_node_reachable(WatchdogNode* wdNode); +static void allocate_resultNodes_in_command(WDCommandData * ipcCommand); +static bool is_node_active_and_reachable(WatchdogNode * wdNode); +static bool is_node_active(WatchdogNode * wdNode); +static bool is_node_reachable(WatchdogNode * wdNode); -static int update_successful_outgoing_cons(fd_set* wmask, int pending_fds_count); -static int prepare_fds(fd_set* rmask, fd_set* wmask, fd_set* emask); +static int update_successful_outgoing_cons(fd_set *wmask, int pending_fds_count); +static int prepare_fds(fd_set *rmask, fd_set *wmask, fd_set *emask); -static void set_next_commandID_in_message(WDPacketData* pkt); -static void set_message_commandID(WDPacketData* pkt, unsigned int commandID); -static void set_message_data(WDPacketData* pkt, const char* data, int len); -static void set_message_type(WDPacketData* pkt, char type); -static void free_packet(WDPacketData *pkt); +static void set_next_commandID_in_message(WDPacketData * pkt); +static void set_message_commandID(WDPacketData * pkt, unsigned int commandID); +static void set_message_data(WDPacketData * pkt, const char *data, int len); +static void set_message_type(WDPacketData * pkt, char type); +static void free_packet(WDPacketData * pkt); -static WDPacketData* get_empty_packet(void); -static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_type); -static WDPacketData* read_packet(SocketConnection* conn); -static WDPacketData* get_message_of_type(char type, WDPacketData* replyFor); -static WDPacketData* get_addnode_message(void); -static WDPacketData* get_beacon_message(char type, WDPacketData* replyFor); -static WDPacketData* get_mynode_info_message(WDPacketData* replyFor); -static WDPacketData* get_minimum_message(char type, WDPacketData* replyFor); +static WDPacketData * get_empty_packet(void); +static WDPacketData * read_packet_of_type(SocketConnection * conn, char ensure_type); +static WDPacketData * read_packet(SocketConnection * conn); +static WDPacketData * get_message_of_type(char type, WDPacketData * replyFor); +static WDPacketData * get_addnode_message(void); +static WDPacketData * get_beacon_message(char type, WDPacketData * replyFor); +static WDPacketData * get_mynode_info_message(WDPacketData * replyFor); +static WDPacketData * get_minimum_message(char type, WDPacketData * replyFor); -static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *pkt, int timeout_sec); +static int issue_watchdog_internal_command(WatchdogNode * wdNode, WDPacketData * pkt, int timeout_sec); static void check_for_current_command_timeout(void); -static bool watchdog_internal_command_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt); +static bool watchdog_internal_command_packet_processor(WatchdogNode * wdNode, WDPacketData * pkt); static bool service_lost_connections(void); static void service_ipc_commands(void); static void service_internal_command(void); static unsigned int get_next_commandID(void); -static WatchdogNode* parse_node_info_message(WDPacketData* pkt, char **authkey); +static WatchdogNode * parse_node_info_message(WDPacketData * pkt, char **authkey); static void update_quorum_status(void); -static int get_mimimum_nodes_required_for_quorum(void); +static int get_mimimum_nodes_required_for_quorum(void); -static bool write_packet_to_socket(int sock, WDPacketData* pkt, bool ipcPacket); -static int read_sockets(fd_set* rmask,int pending_fds_count); +static bool write_packet_to_socket(int sock, WDPacketData * pkt, bool ipcPacket); +static int read_sockets(fd_set *rmask, int pending_fds_count); static void set_timeout(unsigned int sec); -static int wd_create_command_server_socket(void); -static void close_socket_connection(SocketConnection* conn); -static bool send_message_to_connection(SocketConnection* conn, WDPacketData *pkt); +static int wd_create_command_server_socket(void); +static void close_socket_connection(SocketConnection * conn); +static bool send_message_to_connection(SocketConnection * conn, WDPacketData * pkt); -static int send_message(WatchdogNode* wdNode, WDPacketData *pkt); -static bool send_message_to_node(WatchdogNode* wdNode, WDPacketData *pkt); -static bool reply_with_minimal_message(WatchdogNode* wdNode, char type, WDPacketData* replyFor); -static bool reply_with_message(WatchdogNode* wdNode, char type, char* data, int data_len, WDPacketData* replyFor); -static int send_cluster_command(WatchdogNode* wdNode, char type, int timeout_sec); -static int send_message_of_type(WatchdogNode* wdNode, char type, WDPacketData* replyFor); +static int send_message(WatchdogNode * wdNode, WDPacketData * pkt); +static bool send_message_to_node(WatchdogNode * wdNode, WDPacketData * pkt); +static bool reply_with_minimal_message(WatchdogNode * wdNode, char type, WDPacketData * replyFor); +static bool reply_with_message(WatchdogNode * wdNode, char type, char *data, int data_len, WDPacketData * replyFor); +static int send_cluster_command(WatchdogNode * wdNode, char type, int timeout_sec); +static int send_message_of_type(WatchdogNode * wdNode, char type, WDPacketData * replyFor); -static bool send_cluster_service_message(WatchdogNode* wdNode, WDPacketData* replyFor, char message); +static bool send_cluster_service_message(WatchdogNode * wdNode, WDPacketData * replyFor, char message); -static int accept_incomming_connections(fd_set* rmask, int pending_fds_count); +static int accept_incomming_connections(fd_set *rmask, int pending_fds_count); -static int standard_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt); -static void cluster_service_message_processor(WatchdogNode* wdNode, WDPacketData* pkt); -static int get_cluster_node_count(void); -static void clear_command_node_result(WDCommandNodeResult* nodeResult); +static int standard_packet_processor(WatchdogNode * wdNode, WDPacketData * pkt); +static void cluster_service_message_processor(WatchdogNode * wdNode, WDPacketData * pkt); +static int get_cluster_node_count(void); +static void clear_command_node_result(WDCommandNodeResult * nodeResult); static inline bool is_local_node_true_master(void); static inline WD_STATES get_local_node_state(void); -static int set_state(WD_STATES newState); - -static int watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_voting(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_coordinator(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_standForCord(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_initializing(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_joining(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_loading(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); -static int watchdog_state_machine_nw_error(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand); - -static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode); -static void handle_split_brain(WatchdogNode* otherMasterNode, WDPacketData* pkt); -static bool beacon_message_received_from_node(WatchdogNode* wdNode, WDPacketData* pkt); - -static void cleanUpIPCCommand(WDCommandData* ipcCommand); +static int set_state(WD_STATES newState); + +static int watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_voting(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_coordinator(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_standForCord(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_initializing(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_joining(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_loading(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); +static int watchdog_state_machine_nw_error(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand); + +static int I_am_master_and_cluser_in_split_brain(WatchdogNode * otherMasterNode); +static void handle_split_brain(WatchdogNode * otherMasterNode, WDPacketData * pkt); +static bool beacon_message_received_from_node(WatchdogNode * wdNode, WDPacketData * pkt); + +static void cleanUpIPCCommand(WDCommandData * ipcCommand); static bool read_ipc_socket_and_process(int socket, bool *remove_socket); -static JsonNode* get_node_list_json(int id); -static bool add_nodeinfo_to_json(JsonNode* jNode, WatchdogNode* node); +static JsonNode * get_node_list_json(int id); +static bool add_nodeinfo_to_json(JsonNode * jNode, WatchdogNode * node); static bool fire_node_status_event(int nodeID, int nodeStatus); static void resign_from_escalated_node(void); static void start_escalated_node(void); -static void init_wd_packet(WDPacketData* pkt); -static void wd_packet_shallow_copy(WDPacketData* srcPkt, WDPacketData* dstPkt); -static bool wd_commands_packet_processor(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt); - -static WDCommandData* get_wd_command_from_reply(List* commands, WDPacketData* pkt); -static WDCommandData* get_wd_cluster_command_from_reply(WDPacketData* pkt); -static WDCommandData* get_wd_IPC_command_from_reply(WDPacketData* pkt); -static WDCommandData* get_wd_IPC_command_from_socket(int sock); - -static IPC_CMD_PREOCESS_RES process_IPC_command(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_nodeStatusChange_command(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_nodeList_command(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_get_runtime_variable_value_request(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_online_recovery(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData *ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData *ipcCommand); -static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData* ipcCommand); -static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandData* ipcCommand); - -static bool write_ipc_command_with_result_data(WDCommandData* ipcCommand, char type, char* data, int len); +static void init_wd_packet(WDPacketData * pkt); +static void wd_packet_shallow_copy(WDPacketData * srcPkt, WDPacketData * dstPkt); +static bool wd_commands_packet_processor(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt); + +static WDCommandData * get_wd_command_from_reply(List *commands, WDPacketData * pkt); +static WDCommandData * get_wd_cluster_command_from_reply(WDPacketData * pkt); +static WDCommandData * get_wd_IPC_command_from_reply(WDPacketData * pkt); +static WDCommandData * get_wd_IPC_command_from_socket(int sock); + +static IPC_CMD_PREOCESS_RES process_IPC_command(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_nodeStatusChange_command(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_nodeList_command(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_get_runtime_variable_value_request(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_online_recovery(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData * ipcCommand); +static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandData * ipcCommand); + +static bool write_ipc_command_with_result_data(WDCommandData * ipcCommand, char type, char *data, int len); static void process_wd_func_commands_for_timer_events(void); -static void add_wd_command_for_timer_events(unsigned int expire_secs, bool need_tics, WDFunctionCommandData* wd_func_command); -static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* ipcCommand); +static void add_wd_command_for_timer_events(unsigned int expire_secs, bool need_tics, WDFunctionCommandData * wd_func_command); +static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * ipcCommand); -static void process_remote_online_recovery_command(WatchdogNode* wdNode, WDPacketData* pkt); +static void process_remote_online_recovery_command(WatchdogNode * wdNode, WDPacketData * pkt); -static WDFailoverCMDResults failover_end_indication(WDCommandData* ipcCommand); -static WDFailoverCMDResults failover_start_indication(WDCommandData* ipcCommand); +static WDFailoverCMDResults failover_end_indication(WDCommandData * ipcCommand); +static WDFailoverCMDResults failover_start_indication(WDCommandData * ipcCommand); static void wd_system_will_go_down(int code, Datum arg); -static void verify_pool_configurations(WatchdogNode* wdNode, POOL_CONFIG* config); +static void verify_pool_configurations(WatchdogNode * wdNode, POOL_CONFIG * config); -static bool get_authhash_for_node(WatchdogNode* wdNode, char* authhash); -static bool verify_authhash_for_node(WatchdogNode* wdNode, char* authhash); +static bool get_authhash_for_node(WatchdogNode * wdNode, char *authhash); +static bool verify_authhash_for_node(WatchdogNode * wdNode, char *authhash); -static void print_watchdog_node_info(WatchdogNode* wdNode); -static int wd_create_recv_socket(int port); +static void print_watchdog_node_info(WatchdogNode * wdNode); +static int wd_create_recv_socket(int port); static void wd_check_config(void); static pid_t watchdog_main(void); static pid_t fork_watchdog_child(void); -static bool check_IPC_client_authentication(json_value *rootObj, bool internal_client_only); -static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand); +static bool check_IPC_client_authentication(json_value * rootObj, bool internal_client_only); +static bool check_and_report_IPC_authentication(WDCommandData * ipcCommand); -static void print_packet_node_info(WDPacketData* pkt,WatchdogNode* wdNode, bool sending); -static void print_packet_info(WDPacketData* pkt, bool sending); +static void print_packet_node_info(WDPacketData * pkt, WatchdogNode * wdNode, bool sending); +static void print_packet_info(WDPacketData * pkt, bool sending); static void update_interface_status(void); static bool any_interface_available(void); -static WDPacketData* process_data_request(WatchdogNode* wdNode, WDPacketData* pkt); +static WDPacketData * process_data_request(WatchdogNode * wdNode, WDPacketData * pkt); -static WatchdogNode* getMasterWatchdogNode(void); -static void set_cluster_master_node(WatchdogNode* wdNode); +static WatchdogNode * getMasterWatchdogNode(void); +static void set_cluster_master_node(WatchdogNode * wdNode); static void clear_standby_nodes_list(void); -static int standby_node_left_cluster(WatchdogNode* wdNode); -static int standby_node_join_cluster(WatchdogNode* wdNode); +static int standby_node_left_cluster(WatchdogNode * wdNode); +static int standby_node_join_cluster(WatchdogNode * wdNode); /* global variables */ -wd_cluster g_cluster; +wd_cluster g_cluster; struct timeval g_tm_set_time; -int g_timeout_sec = 0; +int g_timeout_sec = 0; -static unsigned int get_next_commandID(void) +static unsigned int +get_next_commandID(void) { return ++g_cluster.nextCommandID; } -static void set_timeout(unsigned int sec) +static void +set_timeout(unsigned int sec) { g_timeout_sec = sec; - gettimeofday(&g_tm_set_time,NULL); + gettimeofday(&g_tm_set_time, NULL); } -pid_t initialize_watchdog(void) +pid_t +initialize_watchdog(void) { if (!pool_config->use_watchdog) return -1; @@ -560,20 +562,21 @@ wd_check_config(void) if (pool_config->wd_remote_nodes.num_wd == 0) ereport(ERROR, (errmsg("invalid watchdog configuration. other pgpools setting is not defined"))); - + if (strlen(pool_config->wd_authkey) > MAX_PASSWORD_SIZE) ereport(ERROR, (errmsg("invalid watchdog configuration. wd_authkey length can't be larger than %d", MAX_PASSWORD_SIZE))); if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB) { - if (pool_config->num_hb_if <= 0) + if (pool_config->num_hb_if <= 0) ereport(ERROR, (errmsg("invalid lifecheck configuration. no heartbeat interfaces defined"))); } } -static void wd_initialize_monitoring_interfaces(void) +static void +wd_initialize_monitoring_interfaces(void) { g_cluster.wdInterfaceToMonitor = NULL; @@ -586,24 +589,25 @@ static void wd_initialize_monitoring_interfaces(void) if (strcasecmp("any", pool_config->wd_monitoring_interfaces_list[0]) == 0) { - struct if_nameindex *if_ni, *idx; - + struct if_nameindex *if_ni, + *idx; + ereport(LOG, (errmsg("ensure availibility on any interface"))); - + if_ni = if_nameindex(); if (if_ni == NULL) { ereport(ERROR, (errmsg("initializing watchdog failed. unable to get network interface information"))); } - - for (idx = if_ni; ! (idx->if_index == 0 && idx->if_name == NULL); idx++) + + for (idx = if_ni; !(idx->if_index == 0 && idx->if_name == NULL); idx++) { - WDInterfaceStatus* if_status; + WDInterfaceStatus *if_status; ereport(DEBUG1, - (errmsg("interface name %s at index %d",idx->if_name,idx->if_index))); + (errmsg("interface name %s at index %d", idx->if_name, idx->if_index))); if (strncasecmp("lo", idx->if_name, 2) == 0) { /* ignoring local interface */ @@ -612,19 +616,19 @@ static void wd_initialize_monitoring_interfaces(void) if_status = palloc(sizeof(WDInterfaceStatus)); if_status->if_name = pstrdup(idx->if_name); if_status->if_index = idx->if_index; - if_status->if_up = true; /* start with optimism */ - g_cluster.wdInterfaceToMonitor = lappend(g_cluster.wdInterfaceToMonitor,if_status); + if_status->if_up = true; /* start with optimism */ + g_cluster.wdInterfaceToMonitor = lappend(g_cluster.wdInterfaceToMonitor, if_status); } if_freenameindex(if_ni); } else { - WDInterfaceStatus* if_status; - char *if_name; - int i; + WDInterfaceStatus *if_status; + char *if_name; + int i; unsigned int if_idx; - for (i=0; i < pool_config->num_wd_monitoring_interfaces_list;i++) + for (i = 0; i < pool_config->num_wd_monitoring_interfaces_list; i++) { if_name = pool_config->wd_monitoring_interfaces_list[i]; /* ignore leading spaces */ @@ -634,27 +638,28 @@ static void wd_initialize_monitoring_interfaces(void) if_idx = if_nametoindex(if_name); if (if_idx == 0) ereport(ERROR, - (errmsg("initializing watchdog failed. invalid interface name \"%s\"",pool_config->wd_monitoring_interfaces_list[0]))); + (errmsg("initializing watchdog failed. invalid interface name \"%s\"", pool_config->wd_monitoring_interfaces_list[0]))); ereport(DEBUG1, - (errmsg("adding monitoring interface [%d] name %s index %d",i,if_name,if_idx))); + (errmsg("adding monitoring interface [%d] name %s index %d", i, if_name, if_idx))); if_status = palloc(sizeof(WDInterfaceStatus)); if_status->if_name = pstrdup(if_name); if_status->if_index = if_idx; - if_status->if_up = true; /* start with optimism */ - g_cluster.wdInterfaceToMonitor = lappend(g_cluster.wdInterfaceToMonitor,if_status); + if_status->if_up = true; /* start with optimism */ + g_cluster.wdInterfaceToMonitor = lappend(g_cluster.wdInterfaceToMonitor, if_status); } } } -static void wd_cluster_initialize(void) +static void +wd_cluster_initialize(void) { - int i = 0; - + int i = 0; + if (pool_config->wd_remote_nodes.num_wd <= 0) { - /* should also have upper limit???*/ + /* should also have upper limit??? */ ereport(ERROR, (errmsg("initializing watchdog failed. no watchdog nodes configured"))); } @@ -666,20 +671,21 @@ static void wd_cluster_initialize(void) g_cluster.localNode->private_id = 0; gettimeofday(&g_cluster.localNode->startup_time, NULL); - strncpy(g_cluster.localNode->hostname, pool_config->wd_hostname, sizeof(g_cluster.localNode->hostname) -1); - strncpy(g_cluster.localNode->delegate_ip, pool_config->delegate_IP, sizeof(g_cluster.localNode->delegate_ip) -1); + strncpy(g_cluster.localNode->hostname, pool_config->wd_hostname, sizeof(g_cluster.localNode->hostname) - 1); + strncpy(g_cluster.localNode->delegate_ip, pool_config->delegate_IP, sizeof(g_cluster.localNode->delegate_ip) - 1); /* Assign the node name */ { struct utsname unameData; + uname(&unameData); snprintf(g_cluster.localNode->nodeName, WD_MAX_HOST_NAMELEN, "%s:%d %s %s", pool_config->wd_hostname, pool_config->port, unameData.sysname, unameData.nodename); - /* should also have upper limit???*/ + /* should also have upper limit??? */ ereport(LOG, - (errmsg("setting the local watchdog node name to \"%s\"",g_cluster.localNode->nodeName))); + (errmsg("setting the local watchdog node name to \"%s\"", g_cluster.localNode->nodeName))); } /* initialize remote nodes */ @@ -687,22 +693,24 @@ static void wd_cluster_initialize(void) g_cluster.remoteNodes = palloc0((sizeof(WatchdogNode) * g_cluster.remoteNodeCount)); ereport(LOG, - (errmsg("watchdog cluster is configured with %d remote nodes",g_cluster.remoteNodeCount))); + (errmsg("watchdog cluster is configured with %d remote nodes", g_cluster.remoteNodeCount))); - for ( i = 0; i < pool_config->wd_remote_nodes.num_wd; i++) + for (i = 0; i < pool_config->wd_remote_nodes.num_wd; i++) { g_cluster.remoteNodes[i].wd_port = pool_config->wd_remote_nodes.wd_remote_node_info[i].wd_port; - g_cluster.remoteNodes[i].private_id = i+1; + g_cluster.remoteNodes[i].private_id = i + 1; g_cluster.remoteNodes[i].pgpool_port = pool_config->wd_remote_nodes.wd_remote_node_info[i].pgpool_port; strcpy(g_cluster.remoteNodes[i].hostname, pool_config->wd_remote_nodes.wd_remote_node_info[i].hostname); - g_cluster.remoteNodes[i].delegate_ip[0] = '\0'; /*this will be populated by remote node*/ + g_cluster.remoteNodes[i].delegate_ip[0] = '\0'; /* this will be + * populated by remote + * node */ ereport(LOG, - (errmsg("watchdog remote node:%d on %s:%d",i,g_cluster.remoteNodes[i].hostname, g_cluster.remoteNodes[i].wd_port))); + (errmsg("watchdog remote node:%d on %s:%d", i, g_cluster.remoteNodes[i].hostname, g_cluster.remoteNodes[i].wd_port))); } g_cluster.clusterMasterInfo.masterNode = NULL; - g_cluster.clusterMasterInfo.standbyNodes = palloc0(sizeof(WatchdogNode*) * g_cluster.remoteNodeCount); + g_cluster.clusterMasterInfo.standbyNodes = palloc0(sizeof(WatchdogNode *) * g_cluster.remoteNodeCount); g_cluster.clusterMasterInfo.standby_nodes_count = 0; g_cluster.clusterMasterInfo.holding_vip = false; g_cluster.quorum_status = -1; @@ -719,7 +727,7 @@ static void wd_cluster_initialize(void) g_cluster.ipc_commands = NULL; g_cluster.localNode->state = WD_DEAD; g_cluster.clusterCommands = NULL; - g_cluster.ipc_auth_needed = strlen(pool_config->wd_authkey)?true:false; + g_cluster.ipc_auth_needed = strlen(pool_config->wd_authkey) ? true : false; g_cluster.localNode->escalated = get_watchdog_node_escalation_state(); @@ -728,7 +736,7 @@ static void wd_cluster_initialize(void) { #ifndef USE_SSL ereport(LOG, - (errmsg("watchdog is configured to use authentication, but pgpool-II is built without SSL support"), + (errmsg("watchdog is configured to use authentication, but pgpool-II is built without SSL support"), errdetail("The authentication method used by pgpool-II without the SSL support is known to be weak"))); #endif } @@ -737,14 +745,16 @@ static void wd_cluster_initialize(void) ereport(LOG, (errmsg("watchdog is recovering from the crash of watchdog process"))); - /* If we are recovering from crash or abnormal termination - * de-escalate the node if it was coordinator when it crashed + /* + * If we are recovering from crash or abnormal termination de-escalate + * the node if it was coordinator when it crashed */ resign_from_escalated_node(); } } -static void clear_command_node_result(WDCommandNodeResult* nodeResult) +static void +clear_command_node_result(WDCommandNodeResult * nodeResult) { nodeResult->result_type = WD_NO_MESSAGE; nodeResult->result_data = NULL; @@ -755,11 +765,11 @@ static void clear_command_node_result(WDCommandNodeResult* nodeResult) static int wd_create_recv_socket(int port) { - size_t len = 0; + size_t len = 0; struct sockaddr_in addr; - int one = 1; - int sock = -1; - int saved_errno; + int one = 1; + int sock = -1; + int saved_errno; if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { @@ -771,7 +781,7 @@ wd_create_recv_socket(int port) pool_set_nonblock(sock); - if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1 ) + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) { /* setsockopt(SO_REUSEADDR) failed */ saved_errno = errno; @@ -780,47 +790,47 @@ wd_create_recv_socket(int port) (errmsg("failed to create watchdog receive socket"), errdetail("setsockopt(SO_REUSEADDR) failed with reason: \"%s\"", strerror(saved_errno)))); } - if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1 ) + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1) { /* setsockopt(TCP_NODELAY) failed */ saved_errno = errno; close(sock); ereport(ERROR, - (errmsg("failed to create watchdog receive socket"), + (errmsg("failed to create watchdog receive socket"), errdetail("setsockopt(TCP_NODELAY) failed with reason: \"%s\"", strerror(saved_errno)))); } - if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1 ) + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1) { /* setsockopt(SO_KEEPALIVE) failed */ saved_errno = errno; close(sock); ereport(ERROR, - (errmsg("failed to create watchdog receive socket"), + (errmsg("failed to create watchdog receive socket"), errdetail("setsockopt(SO_KEEPALIVE) failed with reason: \"%s\"", strerror(saved_errno)))); } - + addr.sin_family = AF_INET; addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); - if ( bind(sock, (struct sockaddr *) & addr, len) < 0 ) + if (bind(sock, (struct sockaddr *) &addr, len) < 0) { /* bind failed */ saved_errno = errno; close(sock); ereport(ERROR, - (errmsg("failed to create watchdog receive socket"), + (errmsg("failed to create watchdog receive socket"), errdetail("bind on \"TCP:%d\" failed with reason: \"%s\"", port, strerror(saved_errno)))); } - if ( listen(sock, MAX_WATCHDOG_NUM * 2) < 0 ) + if (listen(sock, MAX_WATCHDOG_NUM * 2) < 0) { /* listen failed */ saved_errno = errno; close(sock); ereport(ERROR, - (errmsg("failed to create watchdog receive socket"), + (errmsg("failed to create watchdog receive socket"), errdetail("listen failed with reason: \"%s\"", strerror(saved_errno)))); } @@ -834,13 +844,14 @@ wd_create_recv_socket(int port) * the out parameter connected is set to true if the connection is successfull */ static int -wd_create_client_socket(char * hostname, int port, bool *connected) +wd_create_client_socket(char *hostname, int port, bool *connected) { - int sock; - int one = 1; - size_t len = 0; + int sock; + int one = 1; + size_t len = 0; struct sockaddr_in addr; - struct hostent * hp; + struct hostent *hp; + *connected = false; /* create socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) @@ -852,15 +863,15 @@ wd_create_client_socket(char * hostname, int port, bool *connected) } /* set socket option */ - if ( setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1 ) + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *) &one, sizeof(one)) == -1) { close(sock); ereport(LOG, - (errmsg("failed to set socket options"), + (errmsg("failed to set socket options"), errdetail("setsockopt(TCP_NODELAY) failed with error: \"%s\"", strerror(errno)))); return -1; } - if ( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1 ) + if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)) == -1) { ereport(LOG, (errmsg("failed to set socket options"), @@ -869,29 +880,29 @@ wd_create_client_socket(char * hostname, int port, bool *connected) return -1; } /* set sockaddr_in */ - memset(&addr,0,sizeof(addr)); + memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; hp = gethostbyname(hostname); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { - hp = gethostbyaddr(hostname,strlen(hostname),AF_INET); + hp = gethostbyaddr(hostname, strlen(hostname), AF_INET); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) { ereport(LOG, - (errmsg("failed to get host address for \"%s\"",hostname), + (errmsg("failed to get host address for \"%s\"", hostname), errdetail("gethostbyaddr failed with error: \"%s\"", hstrerror(h_errno)))); close(sock); return -1; } } - memmove((char *)&(addr.sin_addr), (char *)hp->h_addr, hp->h_length); + memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); addr.sin_port = htons(port); len = sizeof(struct sockaddr_in); /* set socket to non blocking */ pool_set_nonblock(sock); - if (connect(sock,(struct sockaddr*)&addr, len) < 0) + if (connect(sock, (struct sockaddr *) &addr, len) < 0) { if (errno == EINPROGRESS) { @@ -904,7 +915,7 @@ wd_create_client_socket(char * hostname, int port, bool *connected) return sock; } ereport(LOG, - (errmsg("connect on socket failed"), + (errmsg("connect on socket failed"), errdetail("connect failed with error: \"%s\"", strerror(errno)))); close(sock); return -1; @@ -919,11 +930,13 @@ wd_create_client_socket(char * hostname, int port, bool *connected) static int connect_with_all_configured_nodes(void) { - int connect_count = 0; - int i; - for (i=0; i< g_cluster.remoteNodeCount; i++) + int connect_count = 0; + int i; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (connect_to_node(wdNode)) connect_count++; } @@ -937,10 +950,12 @@ connect_with_all_configured_nodes(void) static void try_connecting_with_all_unreachable_nodes(void) { - int i; - for (i=0; i< g_cluster.remoteNodeCount; i++) + int i; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->client_socket.sock_state != WD_SOCK_WAITING_FOR_CONNECT && wdNode->client_socket.sock_state != WD_SOCK_CONNECTED && wdNode->server_socket.sock_state != WD_SOCK_WAITING_FOR_CONNECT && wdNode->server_socket.sock_state != WD_SOCK_CONNECTED) { @@ -950,7 +965,7 @@ try_connecting_with_all_unreachable_nodes(void) if (wdNode->client_socket.sock_state == WD_SOCK_CONNECTED) { ereport(LOG, - (errmsg("connection to the remote node \"%s\" is restored",wdNode->nodeName))); + (errmsg("connection to the remote node \"%s\" is restored", wdNode->nodeName))); watchdog_state_machine(WD_EVENT_NEW_OUTBOUND_CONNECTION, wdNode, NULL, NULL); } } @@ -961,9 +976,11 @@ try_connecting_with_all_unreachable_nodes(void) * returns true if the connection is in progress or connected successfully * false is returned in case of failure */ -static bool connect_to_node(WatchdogNode* wdNode) +static bool +connect_to_node(WatchdogNode * wdNode) { - bool connected = false; + bool connected = false; + wdNode->client_socket.sock = wd_create_client_socket(wdNode->hostname, wdNode->wd_port, &connected); gettimeofday(&wdNode->client_socket.tv, NULL); if (wdNode->client_socket.sock <= 0) @@ -991,12 +1008,14 @@ static RETSIGTYPE watchdog_signal_handler(int sig) sigchld_request = 1; } -static void check_signals(void) +static void +check_signals(void) { /* reload config file signal? */ if (reload_config_signal) { MemoryContext oldContext = MemoryContextSwitchTo(TopMemoryContext); + pool_get_config(get_config_file_name(), CFGCXT_RELOAD); MemoryContextSwitchTo(oldContext); reload_config_signal = 0; @@ -1011,19 +1030,20 @@ static void check_signals(void) /* * fork a child for watchdog */ -static pid_t fork_watchdog_child(void) +static pid_t +fork_watchdog_child(void) { - pid_t pid; - + pid_t pid; + pid = fork(); - + if (pid == 0) { on_exit_reset(); - + /* Set the process type variable */ processType = PT_WATCHDOG; - + /* call PCP child main */ POOL_SETMASK(&UnBlockSig); watchdog_main(); @@ -1034,7 +1054,7 @@ static pid_t fork_watchdog_child(void) (return_code(POOL_EXIT_FATAL), errmsg("fork() failed. reason: %s", strerror(errno)))); } - + return pid; } @@ -1042,11 +1062,12 @@ static pid_t fork_watchdog_child(void) static int watchdog_main(void) { - fd_set rmask; - fd_set wmask; - fd_set emask; - const int select_timeout = 1; - struct timeval tv, ref_time; + fd_set rmask; + fd_set wmask; + fd_set emask; + const int select_timeout = 1; + struct timeval tv, + ref_time; volatile int fd; sigjmp_buf local_sigjmp_buf; @@ -1060,16 +1081,16 @@ watchdog_main(void) pool_signal(SIGUSR2, SIG_IGN); pool_signal(SIGPIPE, SIG_IGN); pool_signal(SIGALRM, SIG_IGN); - + init_ps_display("", "", "", ""); - + /* Create per loop iteration memory context */ ProcessLoopContext = AllocSetContextCreate(TopMemoryContext, "wd_child_main_loop", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); - + MemoryContextSwitchTo(TopMemoryContext); set_ps_display("watchdog", false); @@ -1081,17 +1102,17 @@ watchdog_main(void) g_cluster.localNode->server_socket.sock_state = WD_SOCK_CONNECTED; /* open the command server */ g_cluster.command_server_sock = wd_create_command_server_socket(); - + /* try connecting to all watchdog nodes */ g_cluster.network_monitor_sock = create_monitoring_socket(); - + if (any_interface_available() == false) { ereport(FATAL, - (return_code(POOL_EXIT_FATAL), + (return_code(POOL_EXIT_FATAL), errmsg("no valid network interface is active"), - errdetail("watchdog requires at least one valid network interface to continue"), - errhint("you can disable interface checking by setting wd_monitoring_interfaces_list = '' in pgpool config"))); + errdetail("watchdog requires at least one valid network interface to continue"), + errhint("you can disable interface checking by setting wd_monitoring_interfaces_list = '' in pgpool config"))); } connect_with_all_configured_nodes(); @@ -1102,12 +1123,12 @@ watchdog_main(void) /* * install the callback for the preparation of system exit */ - on_system_exit(wd_system_will_go_down, (Datum)NULL); + on_system_exit(wd_system_will_go_down, (Datum) NULL); if (sigsetjmp(local_sigjmp_buf, 1) != 0) { /* Since not using PG_TRY, must reset error stack by hand */ - if(fd > 0) + if (fd > 0) close(fd); error_context_stack = NULL; @@ -1121,26 +1142,27 @@ watchdog_main(void) PG_exception_stack = &local_sigjmp_buf; reset_watchdog_process_needs_cleanup(); /* watchdog child loop */ - for(;;) + for (;;) { - int fd_max, select_ret; - bool timeout_event = false; - + int fd_max, + select_ret; + bool timeout_event = false; + MemoryContextSwitchTo(ProcessLoopContext); MemoryContextResetAndDeleteChildren(ProcessLoopContext); check_signals(); - fd_max = prepare_fds(&rmask,&wmask,&emask); + fd_max = prepare_fds(&rmask, &wmask, &emask); tv.tv_sec = select_timeout; tv.tv_usec = 0; select_ret = select(fd_max + 1, &rmask, &wmask, &emask, &tv); - gettimeofday(&ref_time,NULL); + gettimeofday(&ref_time, NULL); - if (g_timeout_sec > 0 ) + if (g_timeout_sec > 0) { - if (WD_TIME_DIFF_SEC(ref_time,g_tm_set_time) >= g_timeout_sec) + if (WD_TIME_DIFF_SEC(ref_time, g_tm_set_time) >= g_timeout_sec) { timeout_event = true; g_timeout_sec = 0; @@ -1148,12 +1170,13 @@ watchdog_main(void) } if (select_ret > 0) { - int processed_fds = 0; + int processed_fds = 0; + processed_fds += accept_incomming_connections(&rmask, (select_ret - processed_fds)); - processed_fds += update_successful_outgoing_cons(&wmask,(select_ret - processed_fds)); - processed_fds += read_sockets(&rmask,(select_ret - processed_fds)); + processed_fds += update_successful_outgoing_cons(&wmask, (select_ret - processed_fds)); + processed_fds += read_sockets(&rmask, (select_ret - processed_fds)); } - if (WD_TIME_DIFF_SEC(ref_time,g_tm_set_time) >= 1) + if (WD_TIME_DIFF_SEC(ref_time, g_tm_set_time) >= 1) { process_wd_func_commands_for_timer_events(); } @@ -1187,64 +1210,69 @@ watchdog_main(void) static int wd_create_command_server_socket(void) { - size_t len = 0; + size_t len = 0; struct sockaddr_un addr; - int sock = -1; + int sock = -1; /* We use unix domain stream sockets for the purpose */ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { /* socket create failed */ ereport(FATAL, - (return_code(POOL_EXIT_FATAL), - errmsg("failed to create watchdog command server socket"), + (return_code(POOL_EXIT_FATAL), + errmsg("failed to create watchdog command server socket"), errdetail("create socket failed with reason: \"%s\"", strerror(errno)))); } memset((char *) &addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path),"%s",get_watchdog_ipc_address()); + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", get_watchdog_ipc_address()); len = sizeof(struct sockaddr_un); ereport(INFO, - (errmsg("IPC socket path: \"%s\"",get_watchdog_ipc_address()))); + (errmsg("IPC socket path: \"%s\"", get_watchdog_ipc_address()))); if (get_watchdog_process_needs_cleanup()) { - /* If we are recovering from crash or abnormal termination - * of watchdog process. Unlink the old socket file + /* + * If we are recovering from crash or abnormal termination of watchdog + * process. Unlink the old socket file */ unlink(addr.sun_path); } - if ( bind(sock, (struct sockaddr *) &addr, len) == -1) + if (bind(sock, (struct sockaddr *) &addr, len) == -1) { - int saved_errno = errno; + int saved_errno = errno; + close(sock); unlink(addr.sun_path); ereport(FATAL, - (return_code(POOL_EXIT_FATAL), - errmsg("failed to create watchdog command server socket"), + (return_code(POOL_EXIT_FATAL), + errmsg("failed to create watchdog command server socket"), errdetail("bind on \"%s\" failed with reason: \"%s\"", addr.sun_path, strerror(saved_errno)))); } - if ( listen(sock, 5) < 0 ) + if (listen(sock, 5) < 0) { /* listen failed */ - int saved_errno = errno; + int saved_errno = errno; + close(sock); unlink(addr.sun_path); ereport(FATAL, - (return_code(POOL_EXIT_FATAL), - errmsg("failed to create watchdog command server socket"), + (return_code(POOL_EXIT_FATAL), + errmsg("failed to create watchdog command server socket"), errdetail("listen failed with reason: \"%s\"", strerror(saved_errno)))); } on_proc_exit(FileUnlink, (Datum) pstrdup(addr.sun_path)); return sock; } -static void FileUnlink(int code, Datum path) +static void +FileUnlink(int code, Datum path) { - char* filePath = (char*)path; + char *filePath = (char *) path; + unlink(filePath); } @@ -1253,122 +1281,130 @@ static void FileUnlink(int code, Datum path) * sets all the valid watchdog cluster descriptors to the fd_set. returns the fd_max */ static int -prepare_fds(fd_set* rmask, fd_set* wmask, fd_set* emask) +prepare_fds(fd_set *rmask, fd_set *wmask, fd_set *emask) { - int i; - ListCell *lc; - int fd_max = g_cluster.localNode->server_socket.sock; - + int i; + ListCell *lc; + int fd_max = g_cluster.localNode->server_socket.sock; + FD_ZERO(rmask); FD_ZERO(wmask); FD_ZERO(emask); - + /* local node server socket will set the read and exception fds */ - FD_SET(g_cluster.localNode->server_socket.sock,rmask); - FD_SET(g_cluster.localNode->server_socket.sock,emask); - + FD_SET(g_cluster.localNode->server_socket.sock, rmask); + FD_SET(g_cluster.localNode->server_socket.sock, emask); + /* command server socket will set the read and exception fds */ - FD_SET(g_cluster.command_server_sock,rmask); - FD_SET(g_cluster.command_server_sock,emask); + FD_SET(g_cluster.command_server_sock, rmask); + FD_SET(g_cluster.command_server_sock, emask); if (fd_max < g_cluster.command_server_sock) fd_max = g_cluster.command_server_sock; - - FD_SET(g_cluster.network_monitor_sock,rmask); + + FD_SET(g_cluster.network_monitor_sock, rmask); if (fd_max < g_cluster.network_monitor_sock) fd_max = g_cluster.network_monitor_sock; - + /* - * set write fdset for all waiting for connection sockets, - * while already connected will be only be waiting for read + * set write fdset for all waiting for connection sockets, while already + * connected will be only be waiting for read */ - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->client_socket.sock > 0) { if (fd_max < wdNode->client_socket.sock) fd_max = wdNode->client_socket.sock; - - FD_SET(wdNode->client_socket.sock,emask); - + + FD_SET(wdNode->client_socket.sock, emask); + if (wdNode->client_socket.sock_state == WD_SOCK_WAITING_FOR_CONNECT) - FD_SET(wdNode->client_socket.sock,wmask); + FD_SET(wdNode->client_socket.sock, wmask); else - FD_SET(wdNode->client_socket.sock,rmask); + FD_SET(wdNode->client_socket.sock, rmask); } if (wdNode->server_socket.sock > 0) { if (fd_max < wdNode->server_socket.sock) fd_max = wdNode->server_socket.sock; - - FD_SET(wdNode->server_socket.sock,emask); - FD_SET(wdNode->server_socket.sock,rmask); + + FD_SET(wdNode->server_socket.sock, emask); + FD_SET(wdNode->server_socket.sock, rmask); } } + /* - * I know this is getting complex but we need to add all incomming unassigned connection sockets - * these one will go for reading + * I know this is getting complex but we need to add all incomming + * unassigned connection sockets these one will go for reading */ foreach(lc, g_cluster.unidentified_socks) { SocketConnection *conn = lfirst(lc); - int ui_sock = conn->sock; + int ui_sock = conn->sock; + if (ui_sock > 0) { - FD_SET(ui_sock,rmask); - FD_SET(ui_sock,emask); + FD_SET(ui_sock, rmask); + FD_SET(ui_sock, emask); if (fd_max < ui_sock) fd_max = ui_sock; } } - + /* Add the notification connected clients */ foreach(lc, g_cluster.notify_clients) { - int ui_sock = lfirst_int(lc); + int ui_sock = lfirst_int(lc); + if (ui_sock > 0) { - FD_SET(ui_sock,rmask); - FD_SET(ui_sock,emask); + FD_SET(ui_sock, rmask); + FD_SET(ui_sock, emask); if (fd_max < ui_sock) fd_max = ui_sock; } } - + /* Finally Add the command IPC sockets */ foreach(lc, g_cluster.ipc_command_socks) { - int ui_sock = lfirst_int(lc); + int ui_sock = lfirst_int(lc); + if (ui_sock > 0) { - FD_SET(ui_sock,rmask); - FD_SET(ui_sock,emask); + FD_SET(ui_sock, rmask); + FD_SET(ui_sock, emask); if (fd_max < ui_sock) fd_max = ui_sock; } } - + return fd_max; } -static int read_sockets(fd_set* rmask,int pending_fds_count) +static int +read_sockets(fd_set *rmask, int pending_fds_count) { - int i,count = 0; - List* socks_to_del = NIL; - ListCell *lc; - - for (i=0; i< g_cluster.remoteNodeCount; i++) + int i, + count = 0; + List *socks_to_del = NIL; + ListCell *lc; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); if (is_socket_connection_connected(&wdNode->client_socket)) { - if ( FD_ISSET(wdNode->client_socket.sock, rmask) ) + if (FD_ISSET(wdNode->client_socket.sock, rmask)) { ereport(DEBUG2, (errmsg("client socket of %s is ready for reading", wdNode->nodeName))); - - WDPacketData* pkt = read_packet(&wdNode->client_socket); + + WDPacketData *pkt = read_packet(&wdNode->client_socket); + if (pkt) { watchdog_state_machine(WD_EVENT_PACKET_RCV, wdNode, pkt, NULL); @@ -1390,11 +1426,12 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) } if (is_socket_connection_connected(&wdNode->server_socket)) { - if ( FD_ISSET(wdNode->server_socket.sock, rmask) ) + if (FD_ISSET(wdNode->server_socket.sock, rmask)) { ereport(DEBUG2, (errmsg("server socket of %s is ready for reading", wdNode->nodeName))); - WDPacketData* pkt = read_packet(&wdNode->server_socket); + WDPacketData *pkt = read_packet(&wdNode->server_socket); + if (pkt) { watchdog_state_machine(WD_EVENT_PACKET_RCV, wdNode, pkt, NULL); @@ -1419,36 +1456,39 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) foreach(lc, g_cluster.unidentified_socks) { SocketConnection *conn = lfirst(lc); - if (conn->sock > 0 && FD_ISSET(conn->sock, rmask)) + + if (conn->sock > 0 && FD_ISSET(conn->sock, rmask)) { - WDPacketData* pkt; + WDPacketData *pkt; + ereport(DEBUG2, - (errmsg("un-identified socket %d is ready for reading",conn->sock))); + (errmsg("un-identified socket %d is ready for reading", conn->sock))); /* we only entertain ADD NODE messages from unidentified sockets */ - pkt = read_packet_of_type(conn,WD_ADD_NODE_MESSAGE); + pkt = read_packet_of_type(conn, WD_ADD_NODE_MESSAGE); if (pkt) { - char *authkey = NULL; - WatchdogNode* tempNode = parse_node_info_message(pkt, &authkey); + char *authkey = NULL; + WatchdogNode *tempNode = parse_node_info_message(pkt, &authkey); + if (tempNode) { - WatchdogNode* wdNode; - bool found = false; - bool authenticated = false; + WatchdogNode *wdNode; + bool found = false; + bool authenticated = false; print_watchdog_node_info(tempNode); authenticated = verify_authhash_for_node(tempNode, authkey); ereport(DEBUG1, - (errmsg("ADD NODE MESSAGE from hostname:\"%s\" port:%d pgpool_port:%d",tempNode->hostname,tempNode->wd_port,tempNode->pgpool_port))); + (errmsg("ADD NODE MESSAGE from hostname:\"%s\" port:%d pgpool_port:%d", tempNode->hostname, tempNode->wd_port, tempNode->pgpool_port))); /* verify this node */ if (authenticated) { - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { wdNode = &(g_cluster.remoteNodes[i]); - - if ( (wdNode->wd_port == tempNode->wd_port && wdNode->pgpool_port == tempNode->pgpool_port) && - ( (strcmp(wdNode->hostname,conn->addr) == 0) || (strcmp(wdNode->hostname,tempNode->hostname) == 0)) ) + + if ((wdNode->wd_port == tempNode->wd_port && wdNode->pgpool_port == tempNode->pgpool_port) && + ((strcmp(wdNode->hostname, conn->addr) == 0) || (strcmp(wdNode->hostname, tempNode->hostname) == 0))) { /* We have found the match */ found = true; @@ -1474,27 +1514,31 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) { /* reply with node info message */ ereport(LOG, - (errmsg("new node joined the cluster hostname:\"%s\" port:%d pgpool_port:%d",tempNode->hostname,tempNode->wd_port,tempNode->pgpool_port))); + (errmsg("new node joined the cluster hostname:\"%s\" port:%d pgpool_port:%d", tempNode->hostname, tempNode->wd_port, tempNode->pgpool_port))); watchdog_state_machine(WD_EVENT_PACKET_RCV, wdNode, pkt, NULL); } else ereport(NOTICE, - (errmsg("add node from hostname:\"%s\" port:%d pgpool_port:%d rejected.",tempNode->hostname,tempNode->wd_port,tempNode->pgpool_port), + (errmsg("add node from hostname:\"%s\" port:%d pgpool_port:%d rejected.", tempNode->hostname, tempNode->wd_port, tempNode->pgpool_port), errdetail("verify the other watchdog node configurations"))); } else { ereport(NOTICE, - (errmsg("authentication failed for add node from hostname:\"%s\" port:%d pgpool_port:%d",tempNode->hostname,tempNode->wd_port,tempNode->pgpool_port), + (errmsg("authentication failed for add node from hostname:\"%s\" port:%d pgpool_port:%d", tempNode->hostname, tempNode->wd_port, tempNode->pgpool_port), errdetail("make sure wd_authkey configuration is same on all nodes"))); } if (found == false || authenticated == false) { - /* reply with reject message, We do not need to go to state processor */ - /* For now, create a empty temp node.*/ + /* + * reply with reject message, We do not need to go to + * state processor + */ + /* For now, create a empty temp node. */ WatchdogNode tmpNode; + tmpNode.client_socket = *conn; tmpNode.client_socket.sock_state = WD_SOCK_CONNECTED; tmpNode.server_socket.sock = -1; @@ -1510,8 +1554,9 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) * Probably some invalid data in the add message */ WatchdogNode tmpNode; + ereport(LOG, - (errmsg("unable to parse the add node message"))); + (errmsg("unable to parse the add node message"))); tmpNode.client_socket = *conn; tmpNode.client_socket.sock_state = WD_SOCK_CONNECTED; tmpNode.server_socket.sock = -1; @@ -1524,17 +1569,17 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) free_packet(pkt); count++; } - socks_to_del = lappend(socks_to_del,conn); + socks_to_del = lappend(socks_to_del, conn); count++; if (count >= pending_fds_count) break; } } - + /* delete all the sockets from unidentified list which are now identified */ foreach(lc, socks_to_del) { - g_cluster.unidentified_socks = list_delete_ptr(g_cluster.unidentified_socks,lfirst(lc)); + g_cluster.unidentified_socks = list_delete_ptr(g_cluster.unidentified_socks, lfirst(lc)); } list_free_deep(socks_to_del); @@ -1545,25 +1590,29 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) foreach(lc, g_cluster.ipc_command_socks) { - int command_sock = lfirst_int(lc); - if (command_sock > 0 && FD_ISSET(command_sock, rmask)) + int command_sock = lfirst_int(lc); + + if (command_sock > 0 && FD_ISSET(command_sock, rmask)) { - bool remove_sock = false; + bool remove_sock = false; + read_ipc_socket_and_process(command_sock, &remove_sock); if (remove_sock) { /* Also locate the command if it has this socket */ - WDCommandData* ipcCommand = get_wd_IPC_command_from_socket(command_sock); + WDCommandData *ipcCommand = get_wd_IPC_command_from_socket(command_sock); + if (ipcCommand) { - /* special case we want to remove the socket from - * ipc_command_sock list manually, so mark the issuing socket - * of ipcComman to invalid value + /* + * special case we want to remove the socket from + * ipc_command_sock list manually, so mark the issuing + * socket of ipcComman to invalid value */ ipcCommand->sourceIPCSocket = -1; } close(command_sock); - socks_to_del = lappend_int(socks_to_del,command_sock); + socks_to_del = lappend_int(socks_to_del, command_sock); } count++; if (count >= pending_fds_count) @@ -1573,26 +1622,28 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) /* delete all the sockets from unidentified list which are now identified */ foreach(lc, socks_to_del) { - g_cluster.ipc_command_socks = list_delete_int(g_cluster.ipc_command_socks,lfirst_int(lc)); + g_cluster.ipc_command_socks = list_delete_int(g_cluster.ipc_command_socks, lfirst_int(lc)); } - + list_free(socks_to_del); socks_to_del = NULL; - + if (count >= pending_fds_count) return count; - + foreach(lc, g_cluster.notify_clients) { - int notify_sock = lfirst_int(lc); - if (notify_sock > 0 && FD_ISSET(notify_sock, rmask)) + int notify_sock = lfirst_int(lc); + + if (notify_sock > 0 && FD_ISSET(notify_sock, rmask)) { - bool remove_sock = false; + bool remove_sock = false; + read_ipc_socket_and_process(notify_sock, &remove_sock); if (remove_sock) { close(notify_sock); - socks_to_del = lappend_int(socks_to_del,notify_sock); + socks_to_del = lappend_int(socks_to_del, notify_sock); } count++; if (count >= pending_fds_count) @@ -1602,25 +1653,26 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) /* delete all the sockets from unidentified list which are now identified */ foreach(lc, socks_to_del) { - g_cluster.notify_clients = list_delete_int(g_cluster.notify_clients,lfirst_int(lc)); + g_cluster.notify_clients = list_delete_int(g_cluster.notify_clients, lfirst_int(lc)); } - + list_free(socks_to_del); socks_to_del = NULL; /* Finally check if something waits us on interface monitoring socket */ - if (g_cluster.network_monitor_sock > 0 && FD_ISSET(g_cluster.network_monitor_sock, rmask)) + if (g_cluster.network_monitor_sock > 0 && FD_ISSET(g_cluster.network_monitor_sock, rmask)) { - bool deleted; - bool link_event; + bool deleted; + bool link_event; + if (read_interface_change_event(g_cluster.network_monitor_sock, &link_event, &deleted)) { ereport(DEBUG1, (errmsg("network event received"), - errdetail("deleted = %s Link change event = %s", - deleted?"YES":"NO", - link_event?"YES":"NO"))); + errdetail("deleted = %s Link change event = %s", + deleted ? "YES" : "NO", + link_event ? "YES" : "NO"))); if (link_event) { if (deleted) @@ -1641,13 +1693,15 @@ static int read_sockets(fd_set* rmask,int pending_fds_count) return count; } -static bool write_ipc_command_with_result_data(WDCommandData* ipcCommand, char type, char* data, int len) +static bool +write_ipc_command_with_result_data(WDCommandData * ipcCommand, char type, char *data, int len) { WDPacketData pkt; + pkt.data = data; pkt.len = len; pkt.type = type; - pkt.command_id = 0; /*command Id is not used in IPC packets*/ + pkt.command_id = 0; /* command Id is not used in IPC packets */ if (ipcCommand == NULL || ipcCommand->commandSource != COMMAND_SOURCE_IPC || ipcCommand->sourceIPCSocket <= 0) { @@ -1658,10 +1712,12 @@ static bool write_ipc_command_with_result_data(WDCommandData* ipcCommand, char t return write_packet_to_socket(ipcCommand->sourceIPCSocket, &pkt, true); } -static WDCommandData* create_command_object(int packet_data_length) +static WDCommandData * create_command_object(int packet_data_length) { - MemoryContext mCxt, oldCxt; - WDCommandData* wdCommand; + MemoryContext mCxt, + oldCxt; + WDCommandData *wdCommand; + /* wd command lives in its own memory context */ mCxt = AllocSetContextCreate(TopMemoryContext, "WDCommand", @@ -1680,35 +1736,37 @@ static WDCommandData* create_command_object(int packet_data_length) return wdCommand; } -static bool read_ipc_socket_and_process(int sock, bool *remove_socket) +static bool +read_ipc_socket_and_process(int sock, bool *remove_socket) { - char type; - int data_len,ret; - WDCommandData* ipcCommand; + char type; + int data_len, + ret; + WDCommandData *ipcCommand; IPC_CMD_PREOCESS_RES res; *remove_socket = true; /* 1st byte is command type */ - ret = socket_read(sock, &type, sizeof(char),0); - if (ret == 0) /* remote end has closed the connection */ + ret = socket_read(sock, &type, sizeof(char), 0); + if (ret == 0) /* remote end has closed the connection */ return false; if (ret != sizeof(char)) { ereport(WARNING, - (errmsg("error reading from IPC socket"), - errdetail("read from socket failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading from IPC socket"), + errdetail("read from socket failed with error \"%s\"", strerror(errno)))); return false; } /* We should have data length */ - ret = socket_read(sock, &data_len, sizeof(int),0); + ret = socket_read(sock, &data_len, sizeof(int), 0); if (ret != sizeof(int)) { ereport(WARNING, - (errmsg("error reading from IPC socket"), - errdetail("read from socket failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading from IPC socket"), + errdetail("read from socket failed with error \"%s\"", strerror(errno)))); return false; } @@ -1724,11 +1782,11 @@ static bool read_ipc_socket_and_process(int sock, bool *remove_socket) if (data_len > 0) { - if (socket_read(sock, ipcCommand->sourcePacket.data , data_len, 0) <= 0) + if (socket_read(sock, ipcCommand->sourcePacket.data, data_len, 0) <= 0) { ereport(LOG, - (errmsg("error reading IPC from socket"), - errdetail("read from socket failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading IPC from socket"), + errdetail("read from socket failed with error \"%s\"", strerror(errno)))); return false; } } @@ -1737,22 +1795,24 @@ static bool read_ipc_socket_and_process(int sock, bool *remove_socket) if (res == IPC_CMD_PROCESSING) { /* - * The command still needs further processing - * store it in the list + * The command still needs further processing store it in the list */ MemoryContext oldCxt; + *remove_socket = false; oldCxt = MemoryContextSwitchTo(TopMemoryContext); - g_cluster.ipc_commands = lappend(g_cluster.ipc_commands,ipcCommand); + g_cluster.ipc_commands = lappend(g_cluster.ipc_commands, ipcCommand); MemoryContextSwitchTo(oldCxt); return true; } else if (res != IPC_CMD_COMPLETE) { - char res_type; - char *data = NULL; - int data_len = 0; - switch (res) { + char res_type; + char *data = NULL; + int data_len = 0; + + switch (res) + { case IPC_CMD_TRY_AGAIN: res_type = WD_IPC_CMD_CLUSTER_IN_TRAN; break; @@ -1775,7 +1835,7 @@ static bool read_ipc_socket_and_process(int sock, bool *remove_socket) data = get_wd_simple_message_json(ipcCommand->errorMessage); data_len = strlen(data) + 1; } - + if (write_ipc_command_with_result_data(ipcCommand, res_type, data, data_len)) { ereport(NOTICE, @@ -1785,23 +1845,24 @@ static bool read_ipc_socket_and_process(int sock, bool *remove_socket) pfree(data); } - /* Delete the Command structure, - * it is as simple as to delete the memory context + /* + * Delete the Command structure, it is as simple as to delete the memory + * context */ MemoryContextDelete(ipcCommand->memoryContext); return (res != IPC_CMD_ERROR); } -static IPC_CMD_PREOCESS_RES process_IPC_command(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_command(WDCommandData * ipcCommand) { /* authenticate the client first */ if (check_and_report_IPC_authentication(ipcCommand) == false) { - /* authentication error is already reported to the caller*/ + /* authentication error is already reported to the caller */ return IPC_CMD_ERROR; } - switch(ipcCommand->sourcePacket.type) + switch (ipcCommand->sourcePacket.type) { case WD_NODE_STATUS_CHANGE_COMMAND: @@ -1809,7 +1870,7 @@ static IPC_CMD_PREOCESS_RES process_IPC_command(WDCommandData* ipcCommand) break; case WD_REGISTER_FOR_NOTIFICATION: - /* Add this socket to the notify socket list*/ + /* Add this socket to the notify socket list */ g_cluster.notify_clients = lappend_int(g_cluster.notify_clients, ipcCommand->sourceIPCSocket); /* The command is completed successfully */ return IPC_CMD_COMPLETE; @@ -1835,29 +1896,30 @@ static IPC_CMD_PREOCESS_RES process_IPC_command(WDCommandData* ipcCommand) case WD_GET_RUNTIME_VARIABLE_VALUE: return process_IPC_get_runtime_variable_value_request(ipcCommand); default: - ipcCommand->errorMessage = MemoryContextStrdup(ipcCommand->memoryContext,"unknown IPC command type"); + ipcCommand->errorMessage = MemoryContextStrdup(ipcCommand->memoryContext, "unknown IPC command type"); break; } return IPC_CMD_ERROR; } -static IPC_CMD_PREOCESS_RES process_IPC_get_runtime_variable_value_request(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_get_runtime_variable_value_request(WDCommandData * ipcCommand) { /* get the json for node list */ - JsonNode* jNode = NULL; - char* requestVarName = NULL; + JsonNode *jNode = NULL; + char *requestVarName = NULL; if (ipcCommand->sourcePacket.len <= 0 || ipcCommand->sourcePacket.data == NULL) return IPC_CMD_ERROR; - json_value *root = json_parse(ipcCommand->sourcePacket.data,ipcCommand->sourcePacket.len); + json_value *root = json_parse(ipcCommand->sourcePacket.data, ipcCommand->sourcePacket.len); + /* The root node must be object */ if (root == NULL || root->type != json_object) { json_value_free(root); ereport(NOTICE, - (errmsg("failed to process get local variable IPC command"), + (errmsg("failed to process get local variable IPC command"), errdetail("unable to parse json data"))); return IPC_CMD_ERROR; } @@ -1882,7 +1944,7 @@ static IPC_CMD_PREOCESS_RES process_IPC_get_runtime_variable_value_request(WDCom else if (strcasecmp(WD_RUNTIME_VAR_QUORUM_STATE, requestVarName) == 0) { jw_put_int(jNode, WD_JSON_KEY_VALUE_DATA_TYPE, VALUE_DATA_TYPE_INT); - jw_put_int(jNode, WD_JSON_KEY_VALUE_DATA, WD_MASTER_NODE?WD_MASTER_NODE->quorum_status:-2); + jw_put_int(jNode, WD_JSON_KEY_VALUE_DATA, WD_MASTER_NODE ? WD_MASTER_NODE->quorum_status : -2); } else if (strcasecmp(WD_RUNTIME_VAR_ESCALATION_STATE, requestVarName) == 0) { @@ -1901,27 +1963,28 @@ static IPC_CMD_PREOCESS_RES process_IPC_get_runtime_variable_value_request(WDCom jw_finish_document(jNode); json_value_free(root); write_ipc_command_with_result_data(ipcCommand, WD_IPC_CMD_RESULT_OK, - jw_get_json_string(jNode), jw_get_json_length(jNode) +1); + jw_get_json_string(jNode), jw_get_json_length(jNode) + 1); jw_destroy(jNode); return IPC_CMD_COMPLETE; } -static IPC_CMD_PREOCESS_RES process_IPC_nodeList_command(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_nodeList_command(WDCommandData * ipcCommand) { /* get the json for node list */ - JsonNode* jNode = NULL; - int NodeID = -1; + JsonNode *jNode = NULL; + int NodeID = -1; if (ipcCommand->sourcePacket.len <= 0 || ipcCommand->sourcePacket.data == NULL) return IPC_CMD_ERROR; - json_value *root = json_parse(ipcCommand->sourcePacket.data,ipcCommand->sourcePacket.len); + json_value *root = json_parse(ipcCommand->sourcePacket.data, ipcCommand->sourcePacket.len); + /* The root node must be object */ if (root == NULL || root->type != json_object) { json_value_free(root); ereport(NOTICE, - (errmsg("failed to process GET NODE LIST IPC command"), + (errmsg("failed to process GET NODE LIST IPC command"), errdetail("unable to parse json data"))); return IPC_CMD_ERROR; } @@ -1935,27 +1998,27 @@ static IPC_CMD_PREOCESS_RES process_IPC_nodeList_command(WDCommandData* ipcComma json_value_free(root); jNode = get_node_list_json(NodeID); write_ipc_command_with_result_data(ipcCommand, WD_IPC_CMD_RESULT_OK, - jw_get_json_string(jNode), jw_get_json_length(jNode) +1); + jw_get_json_string(jNode), jw_get_json_length(jNode) + 1); jw_destroy(jNode); return IPC_CMD_COMPLETE; } -static IPC_CMD_PREOCESS_RES process_IPC_nodeStatusChange_command(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_nodeStatusChange_command(WDCommandData * ipcCommand) { - int nodeStatus; - int nodeID; - char *message; - bool ret; + int nodeStatus; + int nodeID; + char *message; + bool ret; if (ipcCommand->sourcePacket.len <= 0 || ipcCommand->sourcePacket.data == NULL) return IPC_CMD_ERROR; ret = parse_node_status_json(ipcCommand->sourcePacket.data, ipcCommand->sourcePacket.len, &nodeID, &nodeStatus, &message); - + if (ret == false) { ereport(NOTICE, - (errmsg("failed to process NODE STATE CHANGE IPC command"), + (errmsg("failed to process NODE STATE CHANGE IPC command"), errdetail("unable to parse json data"))); return IPC_CMD_ERROR; } @@ -1963,25 +2026,28 @@ static IPC_CMD_PREOCESS_RES process_IPC_nodeStatusChange_command(WDCommandData* if (message) ereport(LOG, (errmsg("received node status change ipc message"), - errdetail("%s",message))); + errdetail("%s", message))); pfree(message); - if (fire_node_status_event(nodeID,nodeStatus) == false) + if (fire_node_status_event(nodeID, nodeStatus) == false) return IPC_CMD_ERROR; - + return IPC_CMD_COMPLETE; } -static bool fire_node_status_event(int nodeID, int nodeStatus) +static bool +fire_node_status_event(int nodeID, int nodeStatus) { - WatchdogNode* wdNode = NULL; - if (nodeID == 0) /* this is reserved for local node */ + WatchdogNode *wdNode = NULL; + + if (nodeID == 0) /* this is reserved for local node */ { wdNode = g_cluster.localNode; } else { - int i; + int i; + for (i = 0; i < g_cluster.remoteNodeCount; i++) { if (nodeID == g_cluster.remoteNodes[i].private_id) @@ -1994,15 +2060,15 @@ static bool fire_node_status_event(int nodeID, int nodeStatus) if (wdNode == NULL) { ereport(LOG, - (errmsg("failed to process node status change event"), + (errmsg("failed to process node status change event"), errdetail("invalid Node ID in the event"))); return false; } - + if (nodeStatus == WD_LIFECHECK_NODE_STATUS_DEAD) { ereport(DEBUG1, - (errmsg("processing node status changed to DEAD event for node ID:%d",nodeID))); + (errmsg("processing node status changed to DEAD event for node ID:%d", nodeID))); if (wdNode == g_cluster.localNode) watchdog_state_machine(WD_EVENT_LOCAL_NODE_LOST, wdNode, NULL, NULL); @@ -2012,7 +2078,7 @@ static bool fire_node_status_event(int nodeID, int nodeStatus) else if (nodeStatus == WD_LIFECHECK_NODE_STATUS_ALIVE) { ereport(DEBUG1, - (errmsg("processing node status changed to ALIVE event for node ID:%d",nodeID))); + (errmsg("processing node status changed to ALIVE event for node ID:%d", nodeID))); if (wdNode == g_cluster.localNode) watchdog_state_machine(WD_EVENT_LOCAL_NODE_FOUND, wdNode, NULL, NULL); @@ -2021,7 +2087,7 @@ static bool fire_node_status_event(int nodeID, int nodeStatus) } else ereport(LOG, - (errmsg("failed to process node status change event"), + (errmsg("failed to process node status change event"), errdetail("invalid event type"))); return true; } @@ -2029,11 +2095,12 @@ static bool fire_node_status_event(int nodeID, int nodeStatus) /* * Free the failover object */ -static void remove_failover_object(WDFailoverObject* failoverObj) +static void +remove_failover_object(WDFailoverObject * failoverObj) { ereport(DEBUG1, - (errmsg("removing failover request from %d nodes with ID:%d", failoverObj->request_count,failoverObj->failoverID))); - g_cluster.wdCurrentFailovers = list_delete_ptr(g_cluster.wdCurrentFailovers,failoverObj); + (errmsg("removing failover request from %d nodes with ID:%d", failoverObj->request_count, failoverObj->failoverID))); + g_cluster.wdCurrentFailovers = list_delete_ptr(g_cluster.wdCurrentFailovers, failoverObj); list_free(failoverObj->requestingNodes); pfree(failoverObj->nodeList); pfree(failoverObj); @@ -2041,44 +2108,48 @@ static void remove_failover_object(WDFailoverObject* failoverObj) /* if the wdNode is NULL. The function removes all failover objects */ -static void clear_all_failovers(void) +static void +clear_all_failovers(void) { - ListCell *lc; - List *failovers_to_del = list_copy(g_cluster.wdCurrentFailovers); + ListCell *lc; + List *failovers_to_del = list_copy(g_cluster.wdCurrentFailovers); ereport(DEBUG1, - (errmsg("Removing all failover objects"))); + (errmsg("Removing all failover objects"))); foreach(lc, failovers_to_del) { - WDFailoverObject* failoverObj = lfirst(lc); + WDFailoverObject *failoverObj = lfirst(lc); + remove_failover_object(failoverObj); } list_free(failovers_to_del); } /* Remove the over stayed failover objects */ -static void service_expired_failovers(void) +static void +service_expired_failovers(void) { - ListCell *lc; - List *failovers_to_del = NULL; + ListCell *lc; + List *failovers_to_del = NULL; struct timeval currTime; if (get_local_node_state() != WD_COORDINATOR) return; - gettimeofday(&currTime,NULL); + gettimeofday(&currTime, NULL); foreach(lc, g_cluster.wdCurrentFailovers) { - WDFailoverObject* failoverObj = lfirst(lc); + WDFailoverObject *failoverObj = lfirst(lc); + if (failoverObj) { - if (WD_TIME_DIFF_SEC(currTime,failoverObj->startTime) >= FAILOVER_COMMAND_FINISH_TIMEOUT) + if (WD_TIME_DIFF_SEC(currTime, failoverObj->startTime) >= FAILOVER_COMMAND_FINISH_TIMEOUT) { - failovers_to_del = lappend(failovers_to_del,failoverObj); + failovers_to_del = lappend(failovers_to_del, failoverObj); ereport(DEBUG1, - (errmsg("failover request from %d nodes with ID:%d is expired", failoverObj->request_count,failoverObj->failoverID), + (errmsg("failover request from %d nodes with ID:%d is expired", failoverObj->request_count, failoverObj->failoverID), errdetail("marking the failover object for removal"))); } @@ -2088,16 +2159,19 @@ static void service_expired_failovers(void) /* delete the failover objects */ foreach(lc, failovers_to_del) { - WDFailoverObject* failoverObj = lfirst(lc); + WDFailoverObject *failoverObj = lfirst(lc); + remove_failover_object(failoverObj); } list_free(failovers_to_del); } -static bool does_int_array_contains_value(int *intArray, int count, int value) +static bool +does_int_array_contains_value(int *intArray, int count, int value) { - int i; - for (i=0; i<count; i++) + int i; + + for (i = 0; i < count; i++) { if (intArray[i] == value) return true; @@ -2105,21 +2179,24 @@ static bool does_int_array_contains_value(int *intArray, int count, int value) return false; } -static WDFailoverObject* get_failover_object(POOL_REQUEST_KIND reqKind, int nodesCount, int *nodeList) +static WDFailoverObject * get_failover_object(POOL_REQUEST_KIND reqKind, int nodesCount, int *nodeList) { - ListCell *lc; + ListCell *lc; + foreach(lc, g_cluster.wdCurrentFailovers) { - WDFailoverObject* failoverObj = lfirst(lc); + WDFailoverObject *failoverObj = lfirst(lc); + if (failoverObj) { if (failoverObj->reqKind == reqKind && failoverObj->nodesCount == nodesCount) { - bool equal = true; - int i; - for (i=0; i<nodesCount; i++) + bool equal = true; + int i; + + for (i = 0; i < nodesCount; i++) { - if (does_int_array_contains_value(nodeList,nodesCount,failoverObj->nodeList[i]) == false) + if (does_int_array_contains_value(nodeList, nodesCount, failoverObj->nodeList[i]) == false) { equal = false; break; @@ -2133,7 +2210,8 @@ static WDFailoverObject* get_failover_object(POOL_REQUEST_KIND reqKind, int node return NULL; } -static void process_remote_failover_command_on_coordinator(WatchdogNode* wdNode, WDPacketData* pkt) +static void +process_remote_failover_command_on_coordinator(WatchdogNode * wdNode, WDPacketData * pkt) { if (get_local_node_state() != WD_COORDINATOR) { @@ -2143,7 +2221,8 @@ static void process_remote_failover_command_on_coordinator(WatchdogNode* wdNode, else { IPC_CMD_PREOCESS_RES res; - WDCommandData* ipcCommand = create_command_object(pkt->len); + WDCommandData *ipcCommand = create_command_object(pkt->len); + ipcCommand->sourcePacket.type = pkt->type; ipcCommand->sourcePacket.len = pkt->len; ipcCommand->sourcePacket.command_id = pkt->command_id; @@ -2156,16 +2235,17 @@ static void process_remote_failover_command_on_coordinator(WatchdogNode* wdNode, gettimeofday(&ipcCommand->commandTime, NULL); ereport(LOG, - (errmsg("watchdog received the failover command from remote pgpool-II node \"%s\"",wdNode->nodeName))); + (errmsg("watchdog received the failover command from remote pgpool-II node \"%s\"", wdNode->nodeName))); res = process_failover_command_on_coordinator(ipcCommand); if (res == IPC_CMD_PROCESSING) { MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); - g_cluster.ipc_commands = lappend(g_cluster.ipc_commands,ipcCommand); + + g_cluster.ipc_commands = lappend(g_cluster.ipc_commands, ipcCommand); MemoryContextSwitchTo(oldCxt); ereport(LOG, - (errmsg("failover command from remote pgpool-II node \"%s\" is still processing",wdNode->nodeName), + (errmsg("failover command from remote pgpool-II node \"%s\" is still processing", wdNode->nodeName), errdetail("waiting for results..."))); } else @@ -2175,10 +2255,12 @@ static void process_remote_failover_command_on_coordinator(WatchdogNode* wdNode, } } -static bool reply_to_failove_command(WDCommandData* ipcCommand, WDFailoverCMDResults cmdResult, unsigned int failoverID) +static bool +reply_to_failove_command(WDCommandData * ipcCommand, WDFailoverCMDResults cmdResult, unsigned int failoverID) { - bool ret = false; - JsonNode* jNode = jw_create_with_object(true); + bool ret = false; + JsonNode *jNode = jw_create_with_object(true); + jw_put_int(jNode, WD_FAILOVER_RESULT_KEY, cmdResult); jw_put_int(jNode, WD_FAILOVER_ID_KEY, failoverID); /* create the packet */ @@ -2186,13 +2268,13 @@ static bool reply_to_failove_command(WDCommandData* ipcCommand, WDFailoverCMDRes jw_finish_document(jNode); ereport(DEBUG2, - (errmsg("replying to failover command with failover ID: %d",failoverID), - errdetail("%.*s",jw_get_json_length(jNode),jw_get_json_string(jNode)))); + (errmsg("replying to failover command with failover ID: %d", failoverID), + errdetail("%.*s", jw_get_json_length(jNode), jw_get_json_string(jNode)))); if (ipcCommand->commandSource == COMMAND_SOURCE_IPC) { ret = write_ipc_command_with_result_data(ipcCommand, WD_IPC_CMD_RESULT_OK, - jw_get_json_string(jNode), jw_get_json_length(jNode) +1); + jw_get_json_string(jNode), jw_get_json_length(jNode) + 1); } else if (ipcCommand->commandSource == COMMAND_SOURCE_REMOTE) { @@ -2209,7 +2291,7 @@ static bool reply_to_failove_command(WDCommandData* ipcCommand, WDFailoverCMDRes * about the execution of failover command. */ -static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind,int *node_id_list, int node_count, unsigned char *flags, WatchdogNode *wdNode) +static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind, int *node_id_list, int node_count, unsigned char *flags, WatchdogNode * wdNode) { #ifndef NODE_UP_REQUIRE_CONSENSUS if (reqKind == NODE_UP_REQUEST) @@ -2227,45 +2309,47 @@ static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind if (pool_config->failover_when_quorum_exists == false) { /* No need for any calculation, We do not need a quorum for failover */ - ereport(LOG,( - errmsg("we do not need quorum to hold to proceed with failover"), - errdetail("proceeding with the failover"), - errhint("failover_when_quorum_exists is set to false"))); + ereport(LOG, ( + errmsg("we do not need quorum to hold to proceed with failover"), + errdetail("proceeding with the failover"), + errhint("failover_when_quorum_exists is set to false"))); return FAILOVER_RES_PROCEED; } if (*flags & REQ_DETAIL_CONFIRMED) { /* Check the request flags, If it asks to bypass the quorum status */ - ereport(LOG,( - errmsg("The failover request does not need quorum to hold"), - errdetail("proceeding with the failover"), - errhint("REQ_DETAIL_CONFIRMED"))); + ereport(LOG, ( + errmsg("The failover request does not need quorum to hold"), + errdetail("proceeding with the failover"), + errhint("REQ_DETAIL_CONFIRMED"))); return FAILOVER_RES_PROCEED; } update_quorum_status(); if (g_cluster.quorum_status < 0) { /* quorum is must and it is not present at the moment */ - ereport(LOG,( - errmsg("failover requires the quorum to hold, which is not present at the moment"), - errdetail("Rejecting the failover request"))); + ereport(LOG, ( + errmsg("failover requires the quorum to hold, which is not present at the moment"), + errdetail("Rejecting the failover request"))); return FAILOVER_RES_NO_QUORUM; } - /* So we reached here means quorum is present - * Now come to dificult part of enusring the consensus + /* + * So we reached here means quorum is present Now come to dificult part of + * enusring the consensus */ if (pool_config->failover_require_consensus == true) { - /* Record the failover.*/ - bool duplicate = false; + /* Record the failover. */ + bool duplicate = false; WDFailoverObject *failoverObj = add_failover(reqKind, node_id_list, node_count, wdNode, *flags, &duplicate); + if (failoverObj->request_count <= get_mimimum_nodes_required_for_quorum()) { - ereport(LOG,( - errmsg("failover requires the majority vote, waiting for consensus"), - errdetail("failover request noted"))); + ereport(LOG, ( + errmsg("failover requires the majority vote, waiting for consensus"), + errdetail("failover request noted"))); if (duplicate && !pool_config->allow_multiple_failover_requests_from_node) return FAILOVER_RES_CONSENSUS_MAY_FAIL; else @@ -2274,9 +2358,9 @@ static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind else { /* We have received enough votes for this failover */ - ereport(LOG,( - errmsg("we have got the consensus to perform the failover"), - errdetail("%d node(s) voted in the favor",failoverObj->request_count))); + ereport(LOG, ( + errmsg("we have got the consensus to perform the failover"), + errdetail("%d node(s) voted in the favor", failoverObj->request_count))); /* restor the flag value to the one from the first call */ *flags = failoverObj->reqFlags; /* remove this object, It is no longer needed */ @@ -2286,28 +2370,32 @@ static WDFailoverCMDResults compute_failover_consensus(POOL_REQUEST_KIND reqKind } else { - ereport(LOG,( - errmsg("we do not require majority votes to proceed with failover"), - errdetail("proceeding with the failover"), - errhint("failover_require_consensus is set to false"))); + ereport(LOG, ( + errmsg("we do not require majority votes to proceed with failover"), + errdetail("proceeding with the failover"), + errhint("failover_require_consensus is set to false"))); } return FAILOVER_RES_PROCEED; } -static WDFailoverObject* add_failover(POOL_REQUEST_KIND reqKind, int *node_id_list, int node_count, WatchdogNode *wdNode, - unsigned char flags, bool *duplicate) +static WDFailoverObject * add_failover(POOL_REQUEST_KIND reqKind, int *node_id_list, int node_count, WatchdogNode * wdNode, + unsigned char flags, bool *duplicate) { MemoryContext oldCxt; + /* Find the failover */ WDFailoverObject *failoverObj = get_failover_object(reqKind, node_count, node_id_list); + *duplicate = false; if (failoverObj) { - ListCell *lc; + ListCell *lc; + /* search the node if it is a duplicate request */ foreach(lc, failoverObj->requestingNodes) { - WatchdogNode* reqWdNode = lfirst(lc); + WatchdogNode *reqWdNode = lfirst(lc); + if (wdNode == reqWdNode) { *duplicate = true; @@ -2315,16 +2403,16 @@ static WDFailoverObject* add_failover(POOL_REQUEST_KIND reqKind, int *node_id_li if (pool_config->allow_multiple_failover_requests_from_node) { failoverObj->request_count++; - ereport(LOG,( - errmsg("duplicate failover request from \"%s\" node",wdNode->nodeName), - errdetail("Pgpool-II can send multiple failover requests for same node"), - errhint("allow_multiple_failover_requests_from_node is enabled"))); + ereport(LOG, ( + errmsg("duplicate failover request from \"%s\" node", wdNode->nodeName), + errdetail("Pgpool-II can send multiple failover requests for same node"), + errhint("allow_multiple_failover_requests_from_node is enabled"))); } else { - ereport(LOG,( - errmsg("Duplicate failover request from \"%s\" node",wdNode->nodeName), - errdetail("request ignored"))); + ereport(LOG, ( + errmsg("Duplicate failover request from \"%s\" node", wdNode->nodeName), + errdetail("request ignored"))); } return failoverObj; } @@ -2346,13 +2434,13 @@ static WDFailoverObject* add_failover(POOL_REQUEST_KIND reqKind, int *node_id_li } failoverObj->failoverID = get_next_commandID(); gettimeofday(&failoverObj->startTime, NULL); - g_cluster.wdCurrentFailovers = lappend(g_cluster.wdCurrentFailovers,failoverObj); + g_cluster.wdCurrentFailovers = lappend(g_cluster.wdCurrentFailovers, failoverObj); MemoryContextSwitchTo(oldCxt); } failoverObj->request_count++; oldCxt = MemoryContextSwitchTo(TopMemoryContext); - failoverObj->requestingNodes = lappend(failoverObj->requestingNodes,wdNode); + failoverObj->requestingNodes = lappend(failoverObj->requestingNodes, wdNode); MemoryContextSwitchTo(oldCxt); return failoverObj; } @@ -2360,26 +2448,26 @@ static WDFailoverObject* add_failover(POOL_REQUEST_KIND reqKind, int *node_id_li /* * The function processes all failover commands on master node */ -static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandData * ipcCommand) { - char* func_name; - int node_count = 0; - int *node_id_list = NULL; - bool ret = false; + char *func_name; + int node_count = 0; + int *node_id_list = NULL; + bool ret = false; unsigned char flags; POOL_REQUEST_KIND reqKind; WDFailoverCMDResults res; if (get_local_node_state() != WD_COORDINATOR) - return IPC_CMD_ERROR; /* should never happen*/ + return IPC_CMD_ERROR; /* should never happen */ ret = parse_wd_node_function_json(ipcCommand->sourcePacket.data, ipcCommand->sourcePacket.len, &func_name, &node_id_list, &node_count, &flags); if (ret == false) { - ereport(LOG,( - errmsg("failed to process failover command"), - errdetail("unable to parse the command data"))); + ereport(LOG, ( + errmsg("failed to process failover command"), + errdetail("unable to parse the command data"))); reply_to_failove_command(ipcCommand, FAILOVER_RES_INVALID_FUNCTION, 0); return IPC_CMD_COMPLETE; } @@ -2399,28 +2487,31 @@ static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandDat ereport(LOG, (errmsg("watchdog is processing the failover command [%s] received from %s", func_name, - ipcCommand->commandSource == COMMAND_SOURCE_IPC? - "local pgpool-II on IPC interface":ipcCommand->sourceWdNode->nodeName))); + ipcCommand->commandSource == COMMAND_SOURCE_IPC ? + "local pgpool-II on IPC interface" : ipcCommand->sourceWdNode->nodeName))); res = compute_failover_consensus(reqKind, node_id_list, node_count, &flags, ipcCommand->sourceWdNode); if (res == FAILOVER_RES_PROCEED) { /* - * We are allowed to proceed with the failover, now - * if the command was originated by the remote node, - * Kick the failover function on the Pgpool-II main process - * and inform the remote caller to wait for sync + * We are allowed to proceed with the failover, now if the command was + * originated by the remote node, Kick the failover function on the + * Pgpool-II main process and inform the remote caller to wait for + * sync */ if (ipcCommand->commandSource == COMMAND_SOURCE_REMOTE) { - /* Set the flag indicating the failover request is originated by watchdog */ + /* + * Set the flag indicating the failover request is originated by + * watchdog + */ flags |= REQ_DETAIL_WATCHDOG; if (reqKind == NODE_DOWN_REQUEST) ret = degenerate_backend_set(node_id_list, node_count, flags); else if (reqKind == NODE_UP_REQUEST) - ret = send_failback_request(node_id_list[0],false, flags); + ret = send_failback_request(node_id_list[0], false, flags); else if (reqKind == PROMOTE_NODE_REQUEST) ret = promote_backend(node_id_list[0], flags); @@ -2432,8 +2523,8 @@ static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandDat else { /* - * It was the request from the local node, - * Just reply the caller to get on with the failover + * It was the request from the local node, Just reply the caller + * to get on with the failover */ reply_to_failove_command(ipcCommand, FAILOVER_RES_PROCEED, 0); } @@ -2452,12 +2543,17 @@ static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandDat (errmsg("failover command [%s] request from pgpool-II node \"%s\" is queued, waiting for the confirmation from other nodes", func_name, ipcCommand->sourceWdNode->nodeName))); + /* - * Ask all the nodes to re-send the failover request for - * the quarantined nodes. + * Ask all the nodes to re-send the failover request for the + * quarantined nodes. */ send_message_of_type(NULL, WD_FAILOVER_WAITING_FOR_CONSENSUS, NULL); - /* Also if the command was originated by remote node, check local quarantine space as-well*/ + + /* + * Also if the command was originated by remote node, check local + * quarantine space as-well + */ if (ipcCommand->commandSource == COMMAND_SOURCE_REMOTE) register_inform_quarantine_nodes_req(); } @@ -2466,7 +2562,7 @@ static IPC_CMD_PREOCESS_RES process_failover_command_on_coordinator(WDCommandDat return IPC_CMD_COMPLETE; } -static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData * ipcCommand) { if (is_local_node_true_master()) { @@ -2481,12 +2577,13 @@ static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData* ipcComma wd_packet_shallow_copy(&ipcCommand->sourcePacket, &ipcCommand->commandPacket); set_next_commandID_in_message(&ipcCommand->commandPacket); - ipcCommand->sendToNode = WD_MASTER_NODE; /* send the command to master node */ + ipcCommand->sendToNode = WD_MASTER_NODE; /* send the command to + * master node */ if (send_command_packet_to_remote_nodes(ipcCommand, true) <= 0) { ereport(LOG, - (errmsg("unable to process the failover command request received on IPC interface"), - errdetail("failed to forward the request to the master watchdog node \"%s\"",WD_MASTER_NODE->nodeName))); + (errmsg("unable to process the failover command request received on IPC interface"), + errdetail("failed to forward the request to the master watchdog node \"%s\"", WD_MASTER_NODE->nodeName))); return IPC_CMD_ERROR; } else @@ -2495,8 +2592,8 @@ static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData* ipcComma * we need to wait for the result */ ereport(LOG, - (errmsg("failover request from local pgpool-II node received on IPC interface is forwarded to master watchdog node \"%s\"", - WD_MASTER_NODE->nodeName), + (errmsg("failover request from local pgpool-II node received on IPC interface is forwarded to master watchdog node \"%s\"", + WD_MASTER_NODE->nodeName), errdetail("waiting for the reply..."))); return IPC_CMD_PROCESSING; } @@ -2505,14 +2602,14 @@ static IPC_CMD_PREOCESS_RES process_IPC_failover_command(WDCommandData* ipcComma { /* we are not in stable state at the moment */ ereport(LOG, - (errmsg("unable to process the failover request received on IPC interface"), + (errmsg("unable to process the failover request received on IPC interface"), errdetail("this watchdog node has not joined the cluster yet"), - errhint("try again in few seconds"))); + errhint("try again in few seconds"))); } return IPC_CMD_ERROR; } -static IPC_CMD_PREOCESS_RES process_IPC_online_recovery(WDCommandData* ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_online_recovery(WDCommandData * ipcCommand) { if (get_local_node_state() == WD_STANDBY || get_local_node_state() == WD_COORDINATOR) @@ -2524,16 +2621,17 @@ static IPC_CMD_PREOCESS_RES process_IPC_online_recovery(WDCommandData* ipcComman wd_packet_shallow_copy(&ipcCommand->sourcePacket, &ipcCommand->commandPacket); set_next_commandID_in_message(&ipcCommand->commandPacket); - ipcCommand->sendToNode = NULL; /* command needs to be sent to all nodes */ + ipcCommand->sendToNode = NULL; /* command needs to be sent to all + * nodes */ if (send_command_packet_to_remote_nodes(ipcCommand, true) <= 0) { ereport(LOG, - (errmsg("unable to process the online recovery request received on IPC interface"), - errdetail("failed to forward the request to the master watchdog node \"%s\"",WD_MASTER_NODE->nodeName))); + (errmsg("unable to process the online recovery request received on IPC interface"), + errdetail("failed to forward the request to the master watchdog node \"%s\"", WD_MASTER_NODE->nodeName))); return IPC_CMD_ERROR; } ereport(LOG, - (errmsg("online recovery request from local pgpool-II node received on IPC interface is forwarded to master watchdog node \"%s\"", + (errmsg("online recovery request from local pgpool-II node received on IPC interface is forwarded to master watchdog node \"%s\"", WD_MASTER_NODE->nodeName), errdetail("waiting for the reply..."))); @@ -2542,18 +2640,18 @@ static IPC_CMD_PREOCESS_RES process_IPC_online_recovery(WDCommandData* ipcComman /* we are not in any stable state at the moment */ ereport(LOG, - (errmsg("unable to process the online recovery request received on IPC interface"), + (errmsg("unable to process the online recovery request received on IPC interface"), errdetail("this watchdog node has not joined the cluster yet"), - errhint("try again in few seconds"))); + errhint("try again in few seconds"))); return IPC_CMD_TRY_AGAIN; } -static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData *ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData * ipcCommand) { /* - * if cluster or myself is not in stable state - * just return cluster in transaction + * if cluster or myself is not in stable state just return cluster in + * transaction */ ereport(LOG, (errmsg("received the get data request from local pgpool-II on IPC interface"))); @@ -2561,8 +2659,8 @@ static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData * if (get_local_node_state() == WD_STANDBY) { /* - * set the command id in the IPC packet before forwaring - * it on the watchdog socket + * set the command id in the IPC packet before forwaring it on the + * watchdog socket */ wd_packet_shallow_copy(&ipcCommand->sourcePacket, &ipcCommand->commandPacket); set_next_commandID_in_message(&ipcCommand->commandPacket); @@ -2571,8 +2669,8 @@ static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData * if (send_command_packet_to_remote_nodes(ipcCommand, true) <= 0) { ereport(LOG, - (errmsg("unable to process the get data request received on IPC interface"), - errdetail("failed to forward the request to the master watchdog node \"%s\"",WD_MASTER_NODE->nodeName))); + (errmsg("unable to process the get data request received on IPC interface"), + errdetail("failed to forward the request to the master watchdog node \"%s\"", WD_MASTER_NODE->nodeName))); return IPC_CMD_ERROR; } else @@ -2581,7 +2679,7 @@ static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData * * we need to wait for the result */ ereport(LOG, - (errmsg("get data request from local pgpool-II node received on IPC interface is forwarded to master watchdog node \"%s\"", + (errmsg("get data request from local pgpool-II node received on IPC interface is forwarded to master watchdog node \"%s\"", WD_MASTER_NODE->nodeName), errdetail("waiting for the reply..."))); @@ -2590,32 +2688,37 @@ static IPC_CMD_PREOCESS_RES process_IPC_data_request_from_master(WDCommandData * } else if (is_local_node_true_master()) { - /* This node is itself a master node, So send the empty result with OK tag */ + /* + * This node is itself a master node, So send the empty result with OK + * tag + */ return IPC_CMD_OK; } /* we are not in any stable state at the moment */ ereport(LOG, - (errmsg("unable to process the get data request received on IPC interface"), + (errmsg("unable to process the get data request received on IPC interface"), errdetail("this watchdog node has not joined the cluster yet"), - errhint("try again in few seconds"))); + errhint("try again in few seconds"))); return IPC_CMD_TRY_AGAIN; } -static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData *ipcCommand) +static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData * ipcCommand) { WDFailoverCMDResults res = FAILOVER_RES_NOT_ALLOWED; + /* - * if cluster or myself is not in stable state - * just return cluster in transaction + * if cluster or myself is not in stable state just return cluster in + * transaction */ ereport(LOG, (errmsg("received the failover indication from Pgpool-II on IPC interface"))); if (get_local_node_state() == WD_COORDINATOR) { - int failoverState = -1; + int failoverState = -1; + if (ipcCommand->sourcePacket.data == NULL || ipcCommand->sourcePacket.len <= 0) { ereport(LOG, @@ -2625,7 +2728,7 @@ static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData *ipcCo } else { - json_value* root = json_parse(ipcCommand->sourcePacket.data,ipcCommand->sourcePacket.len); + json_value *root = json_parse(ipcCommand->sourcePacket.data, ipcCommand->sourcePacket.len); if (root && root->type == json_object) { @@ -2642,18 +2745,18 @@ static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData *ipcCo json_value_free(root); } - if (failoverState < 0 ) + if (failoverState < 0) { ereport(LOG, - (errmsg("unable to process failover indication"), + (errmsg("unable to process failover indication"), errdetail("invalid json data in command packet"))); res = FAILOVER_RES_INVALID_FUNCTION; } - else if (failoverState == 0) /* start */ + else if (failoverState == 0) /* start */ { res = failover_start_indication(ipcCommand); } - else /* end */ + else /* end */ { res = failover_end_indication(ipcCommand); } @@ -2675,10 +2778,10 @@ static IPC_CMD_PREOCESS_RES process_IPC_failover_indication(WDCommandData *ipcCo * only the local node that is a master can start the failover. */ static WDFailoverCMDResults -failover_start_indication(WDCommandData* ipcCommand) +failover_start_indication(WDCommandData * ipcCommand) { ereport(LOG, - (errmsg("watchdog is informed of failover start by the main process"))); + (errmsg("watchdog is informed of failover start by the main process"))); /* only coordinator(master) node is allowed to process failover */ if (get_local_node_state() == WD_COORDINATOR) @@ -2691,7 +2794,7 @@ failover_start_indication(WDCommandData* ipcCommand) { /* The node might be performing the locl quarantine opetaion */ ereport(DEBUG1, - (errmsg("main process is starting the local quarantine operation"))); + (errmsg("main process is starting the local quarantine operation"))); return FAILOVER_RES_PROCEED; } else @@ -2703,7 +2806,7 @@ failover_start_indication(WDCommandData* ipcCommand) } static WDFailoverCMDResults -failover_end_indication(WDCommandData* ipcCommand) +failover_end_indication(WDCommandData * ipcCommand) { ereport(LOG, (errmsg("watchdog is informed of failover end by the main process"))); @@ -2729,37 +2832,37 @@ failover_end_indication(WDCommandData* ipcCommand) return FAILOVER_RES_TRANSITION; } -static WatchdogNode* parse_node_info_message(WDPacketData* pkt, char **authkey) +static WatchdogNode * parse_node_info_message(WDPacketData * pkt, char **authkey) { if (pkt == NULL || (pkt->type != WD_ADD_NODE_MESSAGE && pkt->type != WD_INFO_MESSAGE)) return NULL; if (pkt->data == NULL || pkt->len <= 0) return NULL; - return get_watchdog_node_from_json(pkt->data,pkt->len, authkey); + return get_watchdog_node_from_json(pkt->data, pkt->len, authkey); } -static WDPacketData* read_packet(SocketConnection* conn) +static WDPacketData * read_packet(SocketConnection * conn) { return read_packet_of_type(conn, WD_NO_MESSAGE); } -static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_type) +static WDPacketData * read_packet_of_type(SocketConnection * conn, char ensure_type) { - char type; - int len; + char type; + int len; unsigned int cmd_id; - char* buf; - WDPacketData* pkt = NULL; - int ret; + char *buf; + WDPacketData *pkt = NULL; + int ret; if (is_socket_connection_connected(conn) == false) { ereport(LOG, - (errmsg("error reading from socket connection,socket is not connected"))); + (errmsg("error reading from socket connection,socket is not connected"))); return NULL; } - ret = socket_read(conn->sock,&type, sizeof(char), 1 ); + ret = socket_read(conn->sock, &type, sizeof(char), 1); if (ret != sizeof(char)) { close_socket_connection(conn); @@ -2767,18 +2870,18 @@ static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_typ } ereport(DEBUG1, - (errmsg("received watchdog packet type:%c",type))); + (errmsg("received watchdog packet type:%c", type))); if (ensure_type != WD_NO_MESSAGE && ensure_type != type) { - /* The packet type is not what we want.*/ + /* The packet type is not what we want. */ ereport(DEBUG1, - (errmsg("invalid packet type. expecting %c while received %c",ensure_type,type))); + (errmsg("invalid packet type. expecting %c while received %c", ensure_type, type))); close_socket_connection(conn); return NULL; } - ret = socket_read(conn->sock, &cmd_id, sizeof(int) ,1); + ret = socket_read(conn->sock, &cmd_id, sizeof(int), 1); if (ret != sizeof(int)) { close_socket_connection(conn); @@ -2787,7 +2890,7 @@ static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_typ cmd_id = ntohl(cmd_id); ereport(DEBUG2, - (errmsg("received packet with command id %d from watchdog node ",cmd_id))); + (errmsg("received packet with command id %d from watchdog node ", cmd_id))); ret = socket_read(conn->sock, &len, sizeof(int), 1); if (ret != sizeof(int)) @@ -2799,7 +2902,7 @@ static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_typ len = ntohl(len); ereport(DEBUG1, - (errmsg("reading packet type %c of length %d",type,len))); + (errmsg("reading packet type %c of length %d", type, len))); pkt = get_empty_packet(); set_message_type(pkt, type); @@ -2807,7 +2910,7 @@ static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_typ buf = palloc(len); - ret = socket_read(conn->sock, buf, len,1); + ret = socket_read(conn->sock, buf, len, 1); if (ret != len) { close_socket_connection(conn); @@ -2824,7 +2927,8 @@ static WDPacketData* read_packet_of_type(SocketConnection* conn, char ensure_typ static void wd_child_exit(int exit_signo) { - sigset_t mask; + sigset_t mask; + sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGINT); @@ -2833,10 +2937,11 @@ wd_child_exit(int exit_signo) exit(0); } -static void wd_child_signal_handler(void) +static void +wd_child_signal_handler(void) { - pid_t pid; - int status; + pid_t pid; + int status; ereport(DEBUG1, (errmsg("watchdog process signal handler"))); @@ -2846,7 +2951,7 @@ static void wd_child_signal_handler(void) while ((pid = pool_waitpid(&status)) > 0) { - char *exiting_process_name; + char *exiting_process_name; if (g_cluster.de_escalation_pid == pid) { @@ -2863,46 +2968,49 @@ static void wd_child_signal_handler(void) if (WIFEXITED(status)) { - if(WEXITSTATUS(status) == POOL_EXIT_FATAL) + if (WEXITSTATUS(status) == POOL_EXIT_FATAL) ereport(LOG, - (errmsg("watchdog %s process with pid: %d exit with FATAL ERROR.",exiting_process_name, pid))); - else if(WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) + (errmsg("watchdog %s process with pid: %d exit with FATAL ERROR.", exiting_process_name, pid))); + else if (WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) ereport(LOG, - (errmsg("watchdog %s process with pid: %d exit with SUCCESS.",exiting_process_name, pid))); + (errmsg("watchdog %s process with pid: %d exit with SUCCESS.", exiting_process_name, pid))); } else if (WIFSIGNALED(status)) { /* Child terminated by segmentation fault. Report it */ - if(WTERMSIG(status) == SIGSEGV) + if (WTERMSIG(status) == SIGSEGV) ereport(WARNING, - (errmsg("watchdog %s process with pid: %d was terminated by segmentation fault",exiting_process_name,pid))); + (errmsg("watchdog %s process with pid: %d was terminated by segmentation fault", exiting_process_name, pid))); else ereport(LOG, - (errmsg("watchdog %s process with pid: %d exits with status %d by signal %d",exiting_process_name, pid, status, WTERMSIG(status)))); + (errmsg("watchdog %s process with pid: %d exits with status %d by signal %d", exiting_process_name, pid, status, WTERMSIG(status)))); } else ereport(LOG, - (errmsg("watchdog %s process with pid: %d exits with status %d",exiting_process_name,pid, status))); + (errmsg("watchdog %s process with pid: %d exits with status %d", exiting_process_name, pid, status))); } } /* Function invoked when watchdog process is about to exit */ -static void wd_system_will_go_down(int code, Datum arg) +static void +wd_system_will_go_down(int code, Datum arg) { - int i; + int i; + ereport(LOG, (errmsg("Watchdog is shutting down"))); - + send_cluster_command(NULL, WD_INFORM_I_AM_GOING_DOWN, 0); - + if (get_local_node_state() == WD_COORDINATOR) resign_from_escalated_node(); /* close server socket */ close_socket_connection(&g_cluster.localNode->server_socket); /* close all node sockets */ - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + close_socket_connection(&wdNode->client_socket); close_socket_connection(&wdNode->server_socket); } @@ -2912,15 +3020,17 @@ static void wd_system_will_go_down(int code, Datum arg) /* wait for sub-processes to exit */ if (g_cluster.de_escalation_pid > 0 || g_cluster.escalation_pid > 0) { - pid_t wpid; + pid_t wpid; + do { wpid = wait(NULL); - }while (wpid > 0 || (wpid == -1 && errno == EINTR)); + } while (wpid > 0 || (wpid == -1 && errno == EINTR)); } } -static void close_socket_connection(SocketConnection* conn) +static void +close_socket_connection(SocketConnection * conn) { if ((conn->sock > 0 && conn->sock_state == WD_SOCK_CONNECTED) || conn->sock_state == WD_SOCK_WAITING_FOR_CONNECT) @@ -2931,13 +3041,15 @@ static void close_socket_connection(SocketConnection* conn) } } -static bool is_socket_connection_connected(SocketConnection* conn) +static bool +is_socket_connection_connected(SocketConnection * conn) { return (conn->sock > 0 && conn->sock_state == WD_SOCK_CONNECTED); } -static bool is_node_reachable(WatchdogNode* wdNode) +static bool +is_node_reachable(WatchdogNode * wdNode) { if (is_socket_connection_connected(&wdNode->client_socket)) return true; @@ -2946,34 +3058,38 @@ static bool is_node_reachable(WatchdogNode* wdNode) return false; } -static bool is_node_active(WatchdogNode* wdNode) +static bool +is_node_active(WatchdogNode * wdNode) { if (wdNode->state == WD_DEAD || wdNode->state == WD_LOST || wdNode->state == WD_SHUTDOWN) return false; return true; } -static bool is_node_active_and_reachable(WatchdogNode* wdNode) +static bool +is_node_active_and_reachable(WatchdogNode * wdNode) { if (is_node_active(wdNode)) return is_node_reachable(wdNode); return false; } -static int accept_incomming_connections(fd_set* rmask, int pending_fds_count) +static int +accept_incomming_connections(fd_set *rmask, int pending_fds_count) { - int processed_fds = 0; - int fd; - - if ( FD_ISSET(g_cluster.localNode->server_socket.sock, rmask) ) + int processed_fds = 0; + int fd; + + if (FD_ISSET(g_cluster.localNode->server_socket.sock, rmask)) { struct sockaddr_in addr; - socklen_t addrlen = sizeof(struct sockaddr_in); + socklen_t addrlen = sizeof(struct sockaddr_in); + processed_fds++; - fd = accept(g_cluster.localNode->server_socket.sock, (struct sockaddr *)&addr, &addrlen); + fd = accept(g_cluster.localNode->server_socket.sock, (struct sockaddr *) &addr, &addrlen); if (fd < 0) { - if ( errno == EINTR || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK ) + if (errno == EINTR || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK) { /* nothing to accept now */ ereport(DEBUG2, @@ -2987,13 +3103,13 @@ static int accept_incomming_connections(fd_set* rmask, int pending_fds_count) { MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); SocketConnection *conn = palloc(sizeof(SocketConnection)); - + conn->sock = fd; conn->sock_state = WD_SOCK_CONNECTED; gettimeofday(&conn->tv, NULL); - strncpy(conn->addr,inet_ntoa(addr.sin_addr),sizeof(conn->addr)-1); + strncpy(conn->addr, inet_ntoa(addr.sin_addr), sizeof(conn->addr) - 1); ereport(LOG, - (errmsg("new watchdog node connection is received from \"%s:%d\"",inet_ntoa(addr.sin_addr),addr.sin_port))); + (errmsg("new watchdog node connection is received from \"%s:%d\"", inet_ntoa(addr.sin_addr), addr.sin_port))); g_cluster.unidentified_socks = lappend(g_cluster.unidentified_socks, conn); MemoryContextSwitchTo(oldCxt); } @@ -3002,16 +3118,18 @@ static int accept_incomming_connections(fd_set* rmask, int pending_fds_count) if (processed_fds >= pending_fds_count) return processed_fds; - if ( FD_ISSET(g_cluster.command_server_sock, rmask) ) + if (FD_ISSET(g_cluster.command_server_sock, rmask)) { struct sockaddr addr; - socklen_t addrlen = sizeof(struct sockaddr); + socklen_t addrlen = sizeof(struct sockaddr); + processed_fds++; - int fd = accept(g_cluster.command_server_sock, &addr, &addrlen); + int fd = accept(g_cluster.command_server_sock, &addr, &addrlen); + if (fd < 0) { - if ( errno == EINTR || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK ) + if (errno == EINTR || errno == 0 || errno == EAGAIN || errno == EWOULDBLOCK) { /* nothing to accept now */ ereport(WARNING, @@ -3024,41 +3142,45 @@ static int accept_incomming_connections(fd_set* rmask, int pending_fds_count) else { MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); + ereport(LOG, (errmsg("new IPC connection received"))); g_cluster.ipc_command_socks = lappend_int(g_cluster.ipc_command_socks, fd); MemoryContextSwitchTo(oldCxt); } } - + return processed_fds; } -static int update_successful_outgoing_cons(fd_set* wmask, int pending_fds_count) +static int +update_successful_outgoing_cons(fd_set *wmask, int pending_fds_count) { - int i; - int count = 0; - for (i=0; i< g_cluster.remoteNodeCount; i++) + int i; + int count = 0; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); - + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->client_socket.sock > 0 && wdNode->client_socket.sock_state == WD_SOCK_WAITING_FOR_CONNECT) { - if ( FD_ISSET(wdNode->client_socket.sock, wmask) ) + if (FD_ISSET(wdNode->client_socket.sock, wmask)) { - socklen_t lon; - int valopt; + socklen_t lon; + int valopt; + lon = sizeof(int); gettimeofday(&wdNode->client_socket.tv, NULL); - if (getsockopt(wdNode->client_socket.sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) == 0) + if (getsockopt(wdNode->client_socket.sock, SOL_SOCKET, SO_ERROR, (void *) (&valopt), &lon) == 0) { if (valopt) { ereport(DEBUG1, - (errmsg("error in outbound connection to %s:%d",wdNode->hostname,wdNode->wd_port), - errdetail("%s",strerror(valopt)))); + (errmsg("error in outbound connection to %s:%d", wdNode->hostname, wdNode->wd_port), + errdetail("%s", strerror(valopt)))); close_socket_connection(&wdNode->client_socket); wdNode->client_socket.sock_state = WD_SOCK_ERROR; } @@ -3066,7 +3188,7 @@ static int update_successful_outgoing_cons(fd_set* wmask, int pending_fds_count) { wdNode->client_socket.sock_state = WD_SOCK_CONNECTED; ereport(LOG, - (errmsg("new outbound connection to %s:%d ",wdNode->hostname,wdNode->wd_port))); + (errmsg("new outbound connection to %s:%d ", wdNode->hostname, wdNode->wd_port))); /* set socket to blocking again */ pool_unset_nonblock(wdNode->client_socket.sock); watchdog_state_machine(WD_EVENT_NEW_OUTBOUND_CONNECTION, wdNode, NULL, NULL); @@ -3075,8 +3197,8 @@ static int update_successful_outgoing_cons(fd_set* wmask, int pending_fds_count) else { ereport(DEBUG1, - (errmsg("error in outbound connection to %s:%d ",wdNode->hostname,wdNode->wd_port), - errdetail("getsockopt faile with error \"%s\"",strerror(errno)))); + (errmsg("error in outbound connection to %s:%d ", wdNode->hostname, wdNode->wd_port), + errdetail("getsockopt faile with error \"%s\"", strerror(errno)))); close_socket_connection(&wdNode->client_socket); wdNode->client_socket.sock_state = WD_SOCK_ERROR; @@ -3090,14 +3212,16 @@ static int update_successful_outgoing_cons(fd_set* wmask, int pending_fds_count) return count; } -static bool write_packet_to_socket(int sock, WDPacketData* pkt, bool ipcPacket) +static bool +write_packet_to_socket(int sock, WDPacketData * pkt, bool ipcPacket) { - int ret = 0; - int command_id, len; + int ret = 0; + int command_id, + len; ereport(DEBUG1, - (errmsg("sending watchdog packet to socket:%d, type:[%c], command ID:%d, data Length:%d",sock,pkt->type, - pkt->command_id,pkt->len))); + (errmsg("sending watchdog packet to socket:%d, type:[%c], command ID:%d, data Length:%d", sock, pkt->type, + pkt->command_id, pkt->len))); print_packet_info(pkt, true); @@ -3106,18 +3230,18 @@ static bool write_packet_to_socket(int sock, WDPacketData* pkt, bool ipcPacket) { ereport(LOG, (errmsg("failed to write watchdog packet to socket"), - errdetail("%s",strerror(errno)))); + errdetail("%s", strerror(errno)))); return false; } if (ipcPacket == false) { - /* IPC packets does not have command ID field*/ + /* IPC packets does not have command ID field */ command_id = htonl(pkt->command_id); if (write(sock, &command_id, 4) < 4) { ereport(LOG, - (errmsg("failed to write watchdog packet to socket"), - errdetail("%s",strerror(errno)))); + (errmsg("failed to write watchdog packet to socket"), + errdetail("%s", strerror(errno)))); return false; } } @@ -3126,31 +3250,33 @@ static bool write_packet_to_socket(int sock, WDPacketData* pkt, bool ipcPacket) if (write(sock, &len, 4) < 4) { ereport(LOG, - (errmsg("failed to write watchdog packet to socket"), - errdetail("%s",strerror(errno)))); + (errmsg("failed to write watchdog packet to socket"), + errdetail("%s", strerror(errno)))); return false; } /* DATA */ if (pkt->len > 0 && pkt->data) { - int bytes_send = 0; + int bytes_send = 0; + do { ret = write(sock, pkt->data + bytes_send, (pkt->len - bytes_send)); - if (ret <=0) + if (ret <= 0) { ereport(LOG, - (errmsg("failed to write watchdog packet to socket"), - errdetail("%s",strerror(errno)))); + (errmsg("failed to write watchdog packet to socket"), + errdetail("%s", strerror(errno)))); return false; } bytes_send += ret; - }while (bytes_send < pkt->len); + } while (bytes_send < pkt->len); } return true; } -static void wd_packet_shallow_copy(WDPacketData* srcPkt, WDPacketData* dstPkt) +static void +wd_packet_shallow_copy(WDPacketData * srcPkt, WDPacketData * dstPkt) { dstPkt->command_id = srcPkt->command_id; dstPkt->data = srcPkt->data; @@ -3158,19 +3284,22 @@ static void wd_packet_shallow_copy(WDPacketData* srcPkt, WDPacketData* dstPkt) dstPkt->type = srcPkt->type; } -static void init_wd_packet(WDPacketData* pkt) +static void +init_wd_packet(WDPacketData * pkt) { pkt->len = 0; pkt->data = NULL; } -static WDPacketData* get_empty_packet(void) +static WDPacketData * get_empty_packet(void) { WDPacketData *pkt = palloc0(sizeof(WDPacketData)); + return pkt; } -static void free_packet(WDPacketData *pkt) +static void +free_packet(WDPacketData * pkt) { if (pkt) { @@ -3180,24 +3309,28 @@ static void free_packet(WDPacketData *pkt) } } -static void set_message_type(WDPacketData* pkt, char type) +static void +set_message_type(WDPacketData * pkt, char type) { pkt->type = type; } -static void set_message_commandID(WDPacketData* pkt, unsigned int commandID) +static void +set_message_commandID(WDPacketData * pkt, unsigned int commandID) { pkt->command_id = commandID; } -static void set_next_commandID_in_message(WDPacketData* pkt) +static void +set_next_commandID_in_message(WDPacketData * pkt) { - set_message_commandID(pkt,get_next_commandID()); + set_message_commandID(pkt, get_next_commandID()); } -static void set_message_data(WDPacketData* pkt, const char* data, int len) +static void +set_message_data(WDPacketData * pkt, const char *data, int len) { - pkt->data = (char*)data; + pkt->data = (char *) data; pkt->len = len; } @@ -3205,35 +3338,37 @@ static void set_message_data(WDPacketData* pkt, const char* data, int len) #define nodeIfNull_int(m,v) node?node->m:v #define NotSet "Not_Set" -static bool add_nodeinfo_to_json(JsonNode* jNode, WatchdogNode* node) +static bool +add_nodeinfo_to_json(JsonNode * jNode, WatchdogNode * node) { jw_start_object(jNode, "WatchdogNode"); - - jw_put_int(jNode, "ID", nodeIfNull_int(private_id,-1)); - jw_put_int(jNode, "State", nodeIfNull_int(state,-1)); - jw_put_string(jNode, "NodeName", nodeIfNull_str(nodeName,NotSet)); - jw_put_string(jNode, "HostName", nodeIfNull_str(hostname,NotSet)); - jw_put_string(jNode, "StateName", node?wd_state_names[node->state]:NotSet); - jw_put_string(jNode, "DelegateIP", nodeIfNull_str(delegate_ip,NotSet)); - jw_put_int(jNode, "WdPort", nodeIfNull_int(wd_port,0)); - jw_put_int(jNode, "PgpoolPort", nodeIfNull_int(pgpool_port,0)); - jw_put_int(jNode, "Priority", nodeIfNull_int(wd_priority,0)); + + jw_put_int(jNode, "ID", nodeIfNull_int(private_id, -1)); + jw_put_int(jNode, "State", nodeIfNull_int(state, -1)); + jw_put_string(jNode, "NodeName", nodeIfNull_str(nodeName, NotSet)); + jw_put_string(jNode, "HostName", nodeIfNull_str(hostname, NotSet)); + jw_put_string(jNode, "StateName", node ? wd_state_names[node->state] : NotSet); + jw_put_string(jNode, "DelegateIP", nodeIfNull_str(delegate_ip, NotSet)); + jw_put_int(jNode, "WdPort", nodeIfNull_int(wd_port, 0)); + jw_put_int(jNode, "PgpoolPort", nodeIfNull_int(pgpool_port, 0)); + jw_put_int(jNode, "Priority", nodeIfNull_int(wd_priority, 0)); jw_end_element(jNode); - + return true; } -static JsonNode* get_node_list_json(int id) +static JsonNode * get_node_list_json(int id) { - int i; - JsonNode* jNode = jw_create_with_object(true); + int i; + JsonNode *jNode = jw_create_with_object(true); + jw_put_int(jNode, "RemoteNodeCount", g_cluster.remoteNodeCount); - jw_put_int(jNode, "QuorumStatus", WD_MASTER_NODE?WD_MASTER_NODE->quorum_status:-2); - jw_put_int(jNode, "AliveNodeCount", WD_MASTER_NODE?WD_MASTER_NODE->standby_nodes_count:0); + jw_put_int(jNode, "QuorumStatus", WD_MASTER_NODE ? WD_MASTER_NODE->quorum_status : -2); + jw_put_int(jNode, "AliveNodeCount", WD_MASTER_NODE ? WD_MASTER_NODE->standby_nodes_count : 0); jw_put_int(jNode, "Escalated", g_cluster.localNode->escalated); - jw_put_string(jNode, "MasterNodeName",WD_MASTER_NODE?WD_MASTER_NODE->nodeName:"Not Set"); - jw_put_string(jNode, "MasterHostName",WD_MASTER_NODE?WD_MASTER_NODE->hostname:"Not Set"); + jw_put_string(jNode, "MasterNodeName", WD_MASTER_NODE ? WD_MASTER_NODE->nodeName : "Not Set"); + jw_put_string(jNode, "MasterHostName", WD_MASTER_NODE ? WD_MASTER_NODE->hostname : "Not Set"); if (id < 0) { jw_put_int(jNode, "NodeCount", g_cluster.remoteNodeCount + 1); @@ -3241,11 +3376,12 @@ static JsonNode* get_node_list_json(int id) /* add the array */ jw_start_array(jNode, "WatchdogNodes"); /* add the local node info */ - add_nodeinfo_to_json(jNode,g_cluster.localNode); + add_nodeinfo_to_json(jNode, g_cluster.localNode); /* add all remote nodes */ - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + add_nodeinfo_to_json(jNode, wdNode); } } @@ -3258,15 +3394,17 @@ static JsonNode* get_node_list_json(int id) if (id == 0) { /* add the local node info */ - add_nodeinfo_to_json(jNode,g_cluster.localNode); + add_nodeinfo_to_json(jNode, g_cluster.localNode); } else { /* find from remote nodes */ - WatchdogNode* wdNodeToAdd = NULL; - for (i=0; i< g_cluster.remoteNodeCount; i++) + WatchdogNode *wdNodeToAdd = NULL; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->private_id == id) { wdNodeToAdd = wdNode; @@ -3280,10 +3418,10 @@ static JsonNode* get_node_list_json(int id) return jNode; } -static WDPacketData* get_beacon_message(char type, WDPacketData* replyFor) +static WDPacketData * get_beacon_message(char type, WDPacketData * replyFor) { WDPacketData *message = get_empty_packet(); - char *json_data; + char *json_data; json_data = get_beacon_message_json(g_cluster.localNode); @@ -3294,45 +3432,46 @@ static WDPacketData* get_beacon_message(char type, WDPacketData* replyFor) else set_message_commandID(message, replyFor->command_id); - set_message_data(message,json_data,strlen(json_data)); + set_message_data(message, json_data, strlen(json_data)); return message; } -static WDPacketData* get_addnode_message(void) +static WDPacketData * get_addnode_message(void) { - char authhash[WD_AUTH_HASH_LEN + 1]; + char authhash[WD_AUTH_HASH_LEN + 1]; WDPacketData *message = get_empty_packet(); - bool include_hash = get_authhash_for_node(g_cluster.localNode, authhash); - char *json_data = get_watchdog_node_info_json(g_cluster.localNode, include_hash?authhash:NULL); + bool include_hash = get_authhash_for_node(g_cluster.localNode, authhash); + char *json_data = get_watchdog_node_info_json(g_cluster.localNode, include_hash ? authhash : NULL); set_message_type(message, WD_ADD_NODE_MESSAGE); set_next_commandID_in_message(message); - set_message_data(message,json_data,strlen(json_data)); + set_message_data(message, json_data, strlen(json_data)); return message; } -static WDPacketData* get_mynode_info_message(WDPacketData* replyFor) +static WDPacketData * get_mynode_info_message(WDPacketData * replyFor) { - char authhash[WD_AUTH_HASH_LEN + 1]; + char authhash[WD_AUTH_HASH_LEN + 1]; WDPacketData *message = get_empty_packet(); - bool include_hash = get_authhash_for_node(g_cluster.localNode, authhash); - char *json_data = get_watchdog_node_info_json(g_cluster.localNode, include_hash?authhash:NULL); + bool include_hash = get_authhash_for_node(g_cluster.localNode, authhash); + char *json_data = get_watchdog_node_info_json(g_cluster.localNode, include_hash ? authhash : NULL); set_message_type(message, WD_INFO_MESSAGE); if (replyFor == NULL) set_next_commandID_in_message(message); else set_message_commandID(message, replyFor->command_id); - - set_message_data(message, json_data,strlen(json_data)); + + set_message_data(message, json_data, strlen(json_data)); return message; } -static WDPacketData* get_minimum_message(char type, WDPacketData* replyFor) +static WDPacketData * get_minimum_message(char type, WDPacketData * replyFor) { /* TODO it is a waste of space */ WDPacketData *message = get_empty_packet(); - set_message_type(message,type); + + set_message_type(message, type); if (replyFor == NULL) set_next_commandID_in_message(message); else @@ -3340,31 +3479,32 @@ static WDPacketData* get_minimum_message(char type, WDPacketData* replyFor) return message; } -static WDCommandData* get_wd_IPC_command_from_reply(WDPacketData* pkt) +static WDCommandData * get_wd_IPC_command_from_reply(WDPacketData * pkt) { - return get_wd_command_from_reply(g_cluster.ipc_commands,pkt); + return get_wd_command_from_reply(g_cluster.ipc_commands, pkt); } -static WDCommandData* get_wd_cluster_command_from_reply(WDPacketData* pkt) +static WDCommandData * get_wd_cluster_command_from_reply(WDPacketData * pkt) { - return get_wd_command_from_reply(g_cluster.clusterCommands,pkt); + return get_wd_command_from_reply(g_cluster.clusterCommands, pkt); } -static WDCommandData* get_wd_command_from_reply(List* commands, WDPacketData* pkt) +static WDCommandData * get_wd_command_from_reply(List *commands, WDPacketData * pkt) { - ListCell *lc; + ListCell *lc; if (commands == NULL) return NULL; foreach(lc, commands) { - WDCommandData* ipcCommand = lfirst(lc); + WDCommandData *ipcCommand = lfirst(lc); + if (ipcCommand) { if (ipcCommand->commandPacket.command_id == pkt->command_id) { ereport(DEBUG1, - (errmsg("packet %c with command ID %d is reply to the command %c",pkt->type, pkt->command_id, + (errmsg("packet %c with command ID %d is reply to the command %c", pkt->type, pkt->command_id, ipcCommand->commandPacket.type))); return ipcCommand; } @@ -3373,12 +3513,14 @@ static WDCommandData* get_wd_command_from_reply(List* commands, WDPacketData* pk return NULL; } -static WDCommandData* get_wd_IPC_command_from_socket(int sock) +static WDCommandData * get_wd_IPC_command_from_socket(int sock) { - ListCell *lc; + ListCell *lc; + foreach(lc, g_cluster.ipc_commands) { - WDCommandData* ipcCommand = lfirst(lc); + WDCommandData *ipcCommand = lfirst(lc); + if (ipcCommand) { if (ipcCommand->commandSource != COMMAND_SOURCE_IPC) @@ -3392,52 +3534,53 @@ static WDCommandData* get_wd_IPC_command_from_socket(int sock) } -static void cleanUpIPCCommand(WDCommandData* ipcCommand) +static void +cleanUpIPCCommand(WDCommandData * ipcCommand) { /* - * close the socket associated with ipcCommand - * and remove it from ipcSocket list + * close the socket associated with ipcCommand and remove it from + * ipcSocket list */ if (ipcCommand->commandSource == COMMAND_SOURCE_IPC && ipcCommand->sourceIPCSocket > 0) { close(ipcCommand->sourceIPCSocket); - g_cluster.ipc_command_socks = list_delete_int(g_cluster.ipc_command_socks,ipcCommand->sourceIPCSocket); + g_cluster.ipc_command_socks = list_delete_int(g_cluster.ipc_command_socks, ipcCommand->sourceIPCSocket); ipcCommand->sourceIPCSocket = -1; } /* Now remove the ipcCommand instance from the command list */ - g_cluster.ipc_commands = list_delete_ptr(g_cluster.ipc_commands,ipcCommand); + g_cluster.ipc_commands = list_delete_ptr(g_cluster.ipc_commands, ipcCommand); + /* - * Finally the memory part - * As everything of IPCCommand live inside its own memory context. - * Delete the MemoryContext and we are good + * Finally the memory part As everything of IPCCommand live inside its own + * memory context. Delete the MemoryContext and we are good */ MemoryContextDelete(ipcCommand->memoryContext); } -static WDPacketData* process_data_request(WatchdogNode* wdNode, WDPacketData* pkt) +static WDPacketData * process_data_request(WatchdogNode * wdNode, WDPacketData * pkt) { - char* request_type; - char* data = NULL; - WDPacketData* replyPkt = NULL; + char *request_type; + char *data = NULL; + WDPacketData *replyPkt = NULL; if (pkt->data == NULL || pkt->len <= 0) { ereport(WARNING, - (errmsg("invalid data request packet from watchdog node \"%s\"",wdNode->nodeName), + (errmsg("invalid data request packet from watchdog node \"%s\"", wdNode->nodeName), errdetail("no data found in the packet"))); - replyPkt = get_minimum_message(WD_ERROR_MESSAGE,pkt); + replyPkt = get_minimum_message(WD_ERROR_MESSAGE, pkt); return replyPkt; } - if (!parse_data_request_json(pkt->data,pkt->len, &request_type)) + if (!parse_data_request_json(pkt->data, pkt->len, &request_type)) { ereport(WARNING, - (errmsg("invalid data request packet from watchdog node \"%s\"",wdNode->nodeName), + (errmsg("invalid data request packet from watchdog node \"%s\"", wdNode->nodeName), errdetail("no data found in the packet"))); - replyPkt = get_minimum_message(WD_ERROR_MESSAGE,pkt); + replyPkt = get_minimum_message(WD_ERROR_MESSAGE, pkt); return replyPkt; } @@ -3451,17 +3594,18 @@ static WDPacketData* process_data_request(WatchdogNode* wdNode, WDPacketData* pk replyPkt = get_empty_packet(); set_message_type(replyPkt, WD_DATA_MESSAGE); set_message_commandID(replyPkt, pkt->command_id); - set_message_data(replyPkt, data , strlen(data)); + set_message_data(replyPkt, data, strlen(data)); } else { - replyPkt = get_minimum_message(WD_ERROR_MESSAGE,pkt); + replyPkt = get_minimum_message(WD_ERROR_MESSAGE, pkt); } return replyPkt; } -static void cluster_service_message_processor(WatchdogNode* wdNode, WDPacketData* pkt) +static void +cluster_service_message_processor(WatchdogNode * wdNode, WDPacketData * pkt) { if (pkt->type != WD_CLUSTER_SERVICE_MESSAGE) return; @@ -3469,131 +3613,136 @@ static void cluster_service_message_processor(WatchdogNode* wdNode, WDPacketData if (pkt->len != 1 || pkt->data == NULL) { ereport(LOG, - (errmsg("node \"%s\" sent an invalid cluster service message",wdNode->nodeName))); + (errmsg("node \"%s\" sent an invalid cluster service message", wdNode->nodeName))); return; } switch (pkt->data[0]) { case CLUSTER_IAM_TRUE_MASTER: - { - /* The cluster was in split-brain and remote node thiks it is the worthy master */ - if (get_local_node_state() == WD_COORDINATOR) { - ereport(LOG, - (errmsg("remote node \"%s\" decided it is the true master",wdNode->nodeName), - errdetail("re-initializing the local watchdog cluster state because of split-brain"))); + /* + * The cluster was in split-brain and remote node thiks it is + * the worthy master + */ + if (get_local_node_state() == WD_COORDINATOR) + { + ereport(LOG, + (errmsg("remote node \"%s\" decided it is the true master", wdNode->nodeName), + errdetail("re-initializing the local watchdog cluster state because of split-brain"))); - send_cluster_service_message(NULL,pkt,CLUSTER_IAM_RESIGNING_FROM_MASTER); - set_state(WD_JOINING); - } - else if (WD_MASTER_NODE != NULL && WD_MASTER_NODE != wdNode) - { - ereport(LOG, - (errmsg("remote node \"%s\" thinks it is a master/coordinator and I am causing the split-brain," \ - " but as per our record \"%s\" is the cluster master/coordinator", - wdNode->nodeName, - WD_MASTER_NODE->nodeName), - errdetail("restarting the cluster"))); - send_cluster_service_message(NULL,pkt,CLUSTER_NEEDS_ELECTION); - set_state(WD_JOINING); + send_cluster_service_message(NULL, pkt, CLUSTER_IAM_RESIGNING_FROM_MASTER); + set_state(WD_JOINING); + } + else if (WD_MASTER_NODE != NULL && WD_MASTER_NODE != wdNode) + { + ereport(LOG, + (errmsg("remote node \"%s\" thinks it is a master/coordinator and I am causing the split-brain," \ + " but as per our record \"%s\" is the cluster master/coordinator", + wdNode->nodeName, + WD_MASTER_NODE->nodeName), + errdetail("restarting the cluster"))); + send_cluster_service_message(NULL, pkt, CLUSTER_NEEDS_ELECTION); + set_state(WD_JOINING); + } } - } break; case CLUSTER_IAM_RESIGNING_FROM_MASTER: - { - if (WD_MASTER_NODE == wdNode) { - ereport(LOG, - (errmsg("master/coordinator node \"%s\" decided to resigning from master, probably because of split-brain", - wdNode->nodeName), - errdetail("re-initializing the local watchdog cluster state"))); + if (WD_MASTER_NODE == wdNode) + { + ereport(LOG, + (errmsg("master/coordinator node \"%s\" decided to resigning from master, probably because of split-brain", + wdNode->nodeName), + errdetail("re-initializing the local watchdog cluster state"))); - set_state(WD_JOINING); - } - else - { - ereport(LOG, - (errmsg("master/coordinator node \"%s\" decided to resigning from master, probably because of split-brain", - wdNode->nodeName), - errdetail("but it was not our coordinator/master anyway. ignoring the message"))); + set_state(WD_JOINING); + } + else + { + ereport(LOG, + (errmsg("master/coordinator node \"%s\" decided to resigning from master, probably because of split-brain", + wdNode->nodeName), + errdetail("but it was not our coordinator/master anyway. ignoring the message"))); + } } - } break; case CLUSTER_IN_SPLIT_BRAIN: - { - try_connecting_with_all_unreachable_nodes(); - if (get_local_node_state() == WD_COORDINATOR) { - ereport(LOG, - (errmsg("remote node \"%s\" detected the cluster is in split-brain",wdNode->nodeName), - errdetail("broadcasting the beacon message"))); - send_message_of_type(NULL, WD_IAM_COORDINATOR_MESSAGE, NULL); + try_connecting_with_all_unreachable_nodes(); + if (get_local_node_state() == WD_COORDINATOR) + { + ereport(LOG, + (errmsg("remote node \"%s\" detected the cluster is in split-brain", wdNode->nodeName), + errdetail("broadcasting the beacon message"))); + send_message_of_type(NULL, WD_IAM_COORDINATOR_MESSAGE, NULL); + } } - } break; case CLUSTER_NEEDS_ELECTION: - { - ereport(LOG, - (errmsg("remote node \"%s\" detected the split-brain and wants to re-initialize the cluster",wdNode->nodeName))); + { + ereport(LOG, + (errmsg("remote node \"%s\" detected the split-brain and wants to re-initialize the cluster", wdNode->nodeName))); - set_state(WD_JOINING); - } + set_state(WD_JOINING); + } break; case CLUSTER_IAM_NOT_TRUE_MASTER: - { - if (WD_MASTER_NODE == wdNode) { - ereport(LOG, - (errmsg("master/coordinator node \"%s\" decided it was not true master, probably because of split-brain",wdNode->nodeName), - errdetail("re-initializing the local watchdog cluster state"))); + if (WD_MASTER_NODE == wdNode) + { + ereport(LOG, + (errmsg("master/coordinator node \"%s\" decided it was not true master, probably because of split-brain", wdNode->nodeName), + errdetail("re-initializing the local watchdog cluster state"))); - set_state(WD_JOINING); + set_state(WD_JOINING); + } + else if (get_local_node_state() == WD_COORDINATOR) + { + ereport(LOG, + (errmsg("node \"%s\" was also thinking it was a master/coordinator and decided to resign", wdNode->nodeName), + errdetail("cluster is recovering from split-brain"))); + } + else + { + ereport(LOG, + (errmsg("master/coordinator node \"%s\" decided to resigning from master, probably because of split-brain", + wdNode->nodeName), + errdetail("but it was not our coordinator/master anyway. ignoring the message"))); + } } - else if (get_local_node_state() == WD_COORDINATOR) + break; + + case CLUSTER_NODE_INVALID_VERSION: { - ereport(LOG, - (errmsg("node \"%s\" was also thinking it was a master/coordinator and decided to resign",wdNode->nodeName), - errdetail("cluster is recovering from split-brain"))); - } - else - { - ereport(LOG, - (errmsg("master/coordinator node \"%s\" decided to resigning from master, probably because of split-brain", + /* + * this should never happen means something is seriously wrong + */ + ereport(FATAL, + (errmsg("\"%s\" node has found serious issues in our watchdog messages", wdNode->nodeName), - errdetail("but it was not our coordinator/master anyway. ignoring the message"))); + errdetail("shutting down"))); } - } - break; - - case CLUSTER_NODE_INVALID_VERSION: - { - /* this should never happen - * means something is seriously wrong - */ - ereport(FATAL, - (errmsg("\"%s\" node has found serious issues in our watchdog messages", - wdNode->nodeName), - errdetail("shutting down"))); - } break; default: break; } } -static int standard_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt) +static int +standard_packet_processor(WatchdogNode * wdNode, WDPacketData * pkt) { - WDPacketData* replyPkt = NULL; + WDPacketData *replyPkt = NULL; + switch (pkt->type) { case WD_FAILOVER_WAITING_FOR_CONSENSUS: ereport(LOG, - (errmsg("remote node \"%s\" is asking to inform about quarantined backend nodes",wdNode->nodeName))); + (errmsg("remote node \"%s\" is asking to inform about quarantined backend nodes", wdNode->nodeName))); register_inform_quarantine_nodes_req(); break; @@ -3606,46 +3755,47 @@ static int standard_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt) break; case WD_ASK_FOR_POOL_CONFIG: - { - char* config_data = get_pool_config_json(); - - if (config_data) { - replyPkt = get_empty_packet(); - set_message_type(replyPkt, WD_POOL_CONFIG_DATA); - set_message_commandID(replyPkt, pkt->command_id); - set_message_data(replyPkt, config_data , strlen(config_data)); - } - else - { - replyPkt = get_minimum_message(WD_ERROR_MESSAGE,pkt); + char *config_data = get_pool_config_json(); + + if (config_data) + { + replyPkt = get_empty_packet(); + set_message_type(replyPkt, WD_POOL_CONFIG_DATA); + set_message_commandID(replyPkt, pkt->command_id); + set_message_data(replyPkt, config_data, strlen(config_data)); + } + else + { + replyPkt = get_minimum_message(WD_ERROR_MESSAGE, pkt); + } } - } break; - + case WD_POOL_CONFIG_DATA: - { - /* only accept config data if I am the coordinator node */ - if (get_local_node_state() == WD_COORDINATOR && pkt->data) { - POOL_CONFIG* standby_config = get_pool_config_from_json(pkt->data, pkt->len); - if (standby_config) + /* only accept config data if I am the coordinator node */ + if (get_local_node_state() == WD_COORDINATOR && pkt->data) { - verify_pool_configurations(wdNode, standby_config); + POOL_CONFIG *standby_config = get_pool_config_from_json(pkt->data, pkt->len); + + if (standby_config) + { + verify_pool_configurations(wdNode, standby_config); + } } } - } break; case WD_EVENT_REMOTE_NODE_FOUND: - { - ereport(LOG, - (errmsg("remote node \"%s\" became reachable again",wdNode->nodeName), - errdetail("requesting the node info"))); - send_message_of_type(wdNode,WD_REQ_INFO_MESSAGE,NULL); - break; - } + { + ereport(LOG, + (errmsg("remote node \"%s\" became reachable again", wdNode->nodeName), + errdetail("requesting the node info"))); + send_message_of_type(wdNode, WD_REQ_INFO_MESSAGE, NULL); + break; + } break; case WD_ADD_NODE_MESSAGE: @@ -3654,135 +3804,139 @@ static int standard_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt) break; case WD_INFO_MESSAGE: - { - char *authkey = NULL; - int oldQuorumStatus; - WD_STATES oldNodeState; - WatchdogNode* tempNode = parse_node_info_message(pkt, &authkey); - if (tempNode == NULL) { - ereport(WARNING, - (errmsg("node \"%s\" sent an invalid node info message",wdNode->nodeName))); - send_cluster_service_message(wdNode,pkt,CLUSTER_NODE_INVALID_VERSION); - break; - } - oldQuorumStatus = wdNode->quorum_status; - oldNodeState = wdNode->state; - wdNode->state = tempNode->state; - wdNode->startup_time.tv_sec = tempNode->startup_time.tv_sec; - wdNode->wd_priority = tempNode->wd_priority; - strlcpy(wdNode->nodeName, tempNode->nodeName, WD_MAX_HOST_NAMELEN); + char *authkey = NULL; + int oldQuorumStatus; + WD_STATES oldNodeState; + WatchdogNode *tempNode = parse_node_info_message(pkt, &authkey); - wdNode->current_state_time.tv_sec = tempNode->current_state_time.tv_sec; - wdNode->escalated = tempNode->escalated; - wdNode->standby_nodes_count = tempNode->standby_nodes_count; - wdNode->quorum_status = tempNode->quorum_status; + if (tempNode == NULL) + { + ereport(WARNING, + (errmsg("node \"%s\" sent an invalid node info message", wdNode->nodeName))); + send_cluster_service_message(wdNode, pkt, CLUSTER_NODE_INVALID_VERSION); + break; + } + oldQuorumStatus = wdNode->quorum_status; + oldNodeState = wdNode->state; + wdNode->state = tempNode->state; + wdNode->startup_time.tv_sec = tempNode->startup_time.tv_sec; + wdNode->wd_priority = tempNode->wd_priority; + strlcpy(wdNode->nodeName, tempNode->nodeName, WD_MAX_HOST_NAMELEN); + + wdNode->current_state_time.tv_sec = tempNode->current_state_time.tv_sec; + wdNode->escalated = tempNode->escalated; + wdNode->standby_nodes_count = tempNode->standby_nodes_count; + wdNode->quorum_status = tempNode->quorum_status; - print_watchdog_node_info(wdNode); + print_watchdog_node_info(wdNode); - if (authkey) - pfree(authkey); + if (authkey) + pfree(authkey); - if (wdNode->state == WD_COORDINATOR) - { - if (WD_MASTER_NODE == NULL) - { - set_cluster_master_node(wdNode); - } - else if (WD_MASTER_NODE != wdNode) + if (wdNode->state == WD_COORDINATOR) { - ereport(LOG, - (errmsg("\"%s\" is the coordinator as per our record but \"%s\" is also announcing as a coordinator", - WD_MASTER_NODE->nodeName, wdNode->nodeName), - errdetail("cluster is in the split-brain"))); - - if (get_local_node_state() != WD_COORDINATOR) + if (WD_MASTER_NODE == NULL) { - /* This fight dosen't belong to me - * brodcast the message about cluster in split-brain - */ - - send_cluster_service_message(NULL,pkt,CLUSTER_IN_SPLIT_BRAIN); + set_cluster_master_node(wdNode); } - else + else if (WD_MASTER_NODE != wdNode) { - /* okay the contention is between me and the other node - * try to figure out which node is the worthy master - */ ereport(LOG, - (errmsg("I am the coordinator but \"%s\" is also announcing as a coordinator",wdNode->nodeName), - errdetail("trying to figure out the best contender for the master/coordinator node"))); + (errmsg("\"%s\" is the coordinator as per our record but \"%s\" is also announcing as a coordinator", + WD_MASTER_NODE->nodeName, wdNode->nodeName), + errdetail("cluster is in the split-brain"))); + + if (get_local_node_state() != WD_COORDINATOR) + { + /* + * This fight dosen't belong to me brodcast the + * message about cluster in split-brain + */ + + send_cluster_service_message(NULL, pkt, CLUSTER_IN_SPLIT_BRAIN); + } + else + { + /* + * okay the contention is between me and the other + * node try to figure out which node is the worthy + * master + */ + ereport(LOG, + (errmsg("I am the coordinator but \"%s\" is also announcing as a coordinator", wdNode->nodeName), + errdetail("trying to figure out the best contender for the master/coordinator node"))); - handle_split_brain(wdNode, pkt); + handle_split_brain(wdNode, pkt); + } + } + else if (WD_MASTER_NODE == wdNode && oldQuorumStatus != wdNode->quorum_status) + { + /* inform Pgpool main about quorum status changes */ + register_watchdog_quorum_change_interupt(); } } - else if (WD_MASTER_NODE == wdNode && oldQuorumStatus != wdNode->quorum_status) + + /* + * if the info message is from master node. Make sure we are + * in sync with the master node state + */ + else if (WD_MASTER_NODE == wdNode) { - /* inform Pgpool main about quorum status changes */ - register_watchdog_quorum_change_interupt(); + if (wdNode->state != WD_COORDINATOR) + { + ereport(WARNING, + (errmsg("the coordinator as per our record is not coordinator anymore"), + errdetail("re-initializing the cluster"))); + set_state(WD_JOINING); + } } - } + pfree(tempNode); - /* if the info message is from master node. Make sure we are in sync - * with the master node state - */ - else if (WD_MASTER_NODE == wdNode) - { - if (wdNode->state != WD_COORDINATOR) + if (oldNodeState == WD_STANDBY && wdNode->state != oldNodeState) { - ereport(WARNING, - (errmsg("the coordinator as per our record is not coordinator anymore"), - errdetail("re-initializing the cluster"))); - set_state(WD_JOINING); + standby_node_left_cluster(wdNode); } } - pfree(tempNode); - - if (oldNodeState == WD_STANDBY && wdNode->state != oldNodeState) - { - standby_node_left_cluster(wdNode); - } - } break; case WD_JOIN_COORDINATOR_MESSAGE: - { - /* - * if I am coordinator reply with accept, - * otherwise reject - */ - if (g_cluster.localNode == WD_MASTER_NODE) - { - replyPkt = get_minimum_message(WD_ACCEPT_MESSAGE,pkt); - } - else { - replyPkt = get_minimum_message(WD_REJECT_MESSAGE,pkt); + /* + * if I am coordinator reply with accept, otherwise reject + */ + if (g_cluster.localNode == WD_MASTER_NODE) + { + replyPkt = get_minimum_message(WD_ACCEPT_MESSAGE, pkt); + } + else + { + replyPkt = get_minimum_message(WD_REJECT_MESSAGE, pkt); + } } - } break; - + case WD_IAM_COORDINATOR_MESSAGE: - { - /* - * if the message is received from coordinator reply with info, - * otherwise reject - */ - if (WD_MASTER_NODE != NULL && wdNode != WD_MASTER_NODE) { - ereport(LOG, - (errmsg("\"%s\" is our coordinator node, but \"%s\" is also announcing as a coordinator", - WD_MASTER_NODE->nodeName, wdNode->nodeName), - errdetail("broadcasting the cluster in split-brain message"))); + /* + * if the message is received from coordinator reply with + * info, otherwise reject + */ + if (WD_MASTER_NODE != NULL && wdNode != WD_MASTER_NODE) + { + ereport(LOG, + (errmsg("\"%s\" is our coordinator node, but \"%s\" is also announcing as a coordinator", + WD_MASTER_NODE->nodeName, wdNode->nodeName), + errdetail("broadcasting the cluster in split-brain message"))); - send_cluster_service_message(NULL,pkt,CLUSTER_IN_SPLIT_BRAIN); - } - else - { - replyPkt = get_mynode_info_message(pkt); - beacon_message_received_from_node(wdNode, pkt); + send_cluster_service_message(NULL, pkt, CLUSTER_IN_SPLIT_BRAIN); + } + else + { + replyPkt = get_mynode_info_message(pkt); + beacon_message_received_from_node(wdNode, pkt); + } } - } break; default: @@ -3790,16 +3944,17 @@ static int standard_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt) } if (replyPkt) { - if (send_message_to_node(wdNode,replyPkt) == false) + if (send_message_to_node(wdNode, replyPkt) == false) ereport(LOG, - (errmsg("sending packet to node \"%s\" failed", wdNode->nodeName))); + (errmsg("sending packet to node \"%s\" failed", wdNode->nodeName))); free_packet(replyPkt); } return 1; } -static bool send_message_to_connection(SocketConnection* conn, WDPacketData *pkt) +static bool +send_message_to_connection(SocketConnection * conn, WDPacketData * pkt) { if (conn->sock > 0 && conn->sock_state == WD_SOCK_CONNECTED) { @@ -3813,34 +3968,36 @@ static bool send_message_to_connection(SocketConnection* conn, WDPacketData *pkt return false; } -static bool send_message_to_node(WatchdogNode* wdNode, WDPacketData *pkt) +static bool +send_message_to_node(WatchdogNode * wdNode, WDPacketData * pkt) { - bool ret; + bool ret; - print_packet_node_info(pkt,wdNode, true); + print_packet_node_info(pkt, wdNode, true); - ret = send_message_to_connection(&wdNode->client_socket,pkt); + ret = send_message_to_connection(&wdNode->client_socket, pkt); if (ret == false) { - ret = send_message_to_connection(&wdNode->server_socket,pkt); + ret = send_message_to_connection(&wdNode->server_socket, pkt); } if (ret) { /* we only update the last sent time if reply for packet is expected */ - switch (pkt->type) { + switch (pkt->type) + { case WD_REMOTE_FAILOVER_REQUEST: case WD_IPC_FAILOVER_COMMAND: if (wdNode->last_sent_time.tv_sec <= 0) gettimeofday(&wdNode->last_sent_time, NULL); break; default: - break; + break; } } else { ereport(DEBUG1, - (errmsg("sending packet %c to node \"%s\" failed", pkt->type,wdNode->nodeName))); + (errmsg("sending packet %c to node \"%s\" failed", pkt->type, wdNode->nodeName))); } return ret; } @@ -3849,36 +4006,40 @@ static bool send_message_to_node(WatchdogNode* wdNode, WDPacketData *pkt) * If wdNode is NULL message is sent to all nodes * Returns the number of nodes the message is sent to */ -static int send_message(WatchdogNode* wdNode, WDPacketData *pkt) +static int +send_message(WatchdogNode * wdNode, WDPacketData * pkt) { - int i,count = 0; + int i, + count = 0; + if (wdNode) { - if (wdNode == g_cluster.localNode) /*Always return 1 if I myself is intended receiver */ + if (wdNode == g_cluster.localNode) /* Always return 1 if I myself is + * intended receiver */ return 1; - if (send_message_to_node(wdNode,pkt)) + if (send_message_to_node(wdNode, pkt)) return 1; return 0; } /* NULL means send to all reachable nodes */ - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { wdNode = &(g_cluster.remoteNodes[i]); - if (is_node_reachable(wdNode) && send_message_to_node(wdNode,pkt)) + if (is_node_reachable(wdNode) && send_message_to_node(wdNode, pkt)) count++; } return count; } -static IPC_CMD_PREOCESS_RES wd_command_processor_for_node_lost_event(WDCommandData* ipcCommand, WatchdogNode* wdLostNode) +static IPC_CMD_PREOCESS_RES wd_command_processor_for_node_lost_event(WDCommandData * ipcCommand, WatchdogNode * wdLostNode) { if (ipcCommand->sendToNode) { /* The command was sent to one node only */ if (ipcCommand->sendToNode == wdLostNode) { - /* Fail this command, Since the only - * node it was sent to is lost + /* + * Fail this command, Since the only node it was sent to is lost */ ipcCommand->commandStatus = COMMAND_FINISHED_SEND_FAILED; wd_command_is_complete(ipcCommand); @@ -3893,26 +4054,31 @@ static IPC_CMD_PREOCESS_RES wd_command_processor_for_node_lost_event(WDCommandDa else { /* search the node that is lost */ - int i; - for (i=0; i< g_cluster.remoteNodeCount; i++) + int i; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeResult = &ipcCommand->nodeResults[i]; + WDCommandNodeResult *nodeResult = &ipcCommand->nodeResults[i]; + if (nodeResult->wdNode == wdLostNode) { if (nodeResult->cmdState == COMMAND_STATE_SENT) { ereport(LOG, - (errmsg("remote node \"%s\" lost while ipc command was in progress ",wdLostNode->nodeName))); - /* since the node is lost and will be removed from the cluster - * So remove decrement the sent count of command and see what is - * the situation after that + (errmsg("remote node \"%s\" lost while ipc command was in progress ", wdLostNode->nodeName))); + + /* + * since the node is lost and will be removed from the + * cluster So remove decrement the sent count of command + * and see what is the situation after that */ nodeResult->cmdState = COMMAND_STATE_DO_NOT_SEND; ipcCommand->commandSendToCount--; if (ipcCommand->commandSendToCount <= ipcCommand->commandReplyFromCount) { - /* If we have already received the results from all alive nodes - * finish the command + /* + * If we have already received the results from all + * alive nodes finish the command */ ipcCommand->commandStatus = COMMAND_FINISHED_ALL_REPLIED; wd_command_is_complete(ipcCommand); @@ -3926,20 +4092,24 @@ static IPC_CMD_PREOCESS_RES wd_command_processor_for_node_lost_event(WDCommandDa return IPC_CMD_PROCESSING; } -static void wd_command_is_complete(WDCommandData* ipcCommand) +static void +wd_command_is_complete(WDCommandData * ipcCommand) { if (ipcCommand->commandCompleteFunc) { ipcCommand->commandCompleteFunc(ipcCommand); return; } - /* There is not special function for this command - * use the standard reply + + /* + * There is not special function for this command use the standard reply */ if (ipcCommand->commandSource == COMMAND_SOURCE_IPC) { - char res_type; - switch (ipcCommand->commandStatus) { + char res_type; + + switch (ipcCommand->commandStatus) + { case COMMAND_FINISHED_ALL_REPLIED: res_type = WD_IPC_CMD_RESULT_OK; break; @@ -3951,14 +4121,14 @@ static void wd_command_is_complete(WDCommandData* ipcCommand) res_type = WD_IPC_CMD_RESULT_BAD; break; default: - res_type= WD_IPC_CMD_RESULT_OK; + res_type = WD_IPC_CMD_RESULT_OK; break; } write_ipc_command_with_result_data(ipcCommand, res_type, NULL, 0); } else if (ipcCommand->commandSource == COMMAND_SOURCE_REMOTE) { - char res_type; + char res_type; if (ipcCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED) res_type = WD_ACCEPT_MESSAGE; @@ -3970,23 +4140,27 @@ static void wd_command_is_complete(WDCommandData* ipcCommand) } -static void node_lost_while_ipc_command(WatchdogNode* wdNode) +static void +node_lost_while_ipc_command(WatchdogNode * wdNode) { - List* ipcCommands_to_del = NIL; - ListCell *lc; + List *ipcCommands_to_del = NIL; + ListCell *lc; + foreach(lc, g_cluster.ipc_commands) { - WDCommandData* ipcCommand = lfirst(lc); + WDCommandData *ipcCommand = lfirst(lc); IPC_CMD_PREOCESS_RES res = wd_command_processor_for_node_lost_event(ipcCommand, wdNode); + if (res != IPC_CMD_PROCESSING) { - ipcCommands_to_del = lappend(ipcCommands_to_del,ipcCommand); + ipcCommands_to_del = lappend(ipcCommands_to_del, ipcCommand); } } /* delete completed commands */ foreach(lc, ipcCommands_to_del) { - WDCommandData* ipcCommand = lfirst(lc); + WDCommandData *ipcCommand = lfirst(lc); + cleanUpIPCCommand(ipcCommand); } } @@ -3996,25 +4170,29 @@ static void node_lost_while_ipc_command(WatchdogNode* wdNode) * The function walks through all command and resends * the failed maessage again if it can. */ -static void service_ipc_commands(void) +static void +service_ipc_commands(void) { - ListCell *lc; + ListCell *lc; + foreach(lc, g_cluster.ipc_commands) { - WDCommandData* ipcCommand = lfirst(lc); + WDCommandData *ipcCommand = lfirst(lc); if (ipcCommand && ipcCommand->commandSendToErrorCount) { - int i; - for (i=0; i< g_cluster.remoteNodeCount; i++) + int i; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeResult = &ipcCommand->nodeResults[i]; + WDCommandNodeResult *nodeResult = &ipcCommand->nodeResults[i]; + if (nodeResult->cmdState == COMMAND_STATE_SEND_ERROR) { if (is_node_active_and_reachable(nodeResult->wdNode)) { ereport(LOG, - (errmsg("remote node \"%s\" is reachable again, resending the command packet ",nodeResult->wdNode->nodeName))); + (errmsg("remote node \"%s\" is reachable again, resending the command packet ", nodeResult->wdNode->nodeName))); if (send_message_to_node(nodeResult->wdNode, &ipcCommand->commandPacket) == true) { @@ -4031,28 +4209,31 @@ static void service_ipc_commands(void) } } -static void service_internal_command(void) +static void +service_internal_command(void) { - int i; - ListCell *lc; - List *finishedCommands = NULL; + int i; + ListCell *lc; + List *finishedCommands = NULL; if (g_cluster.clusterCommands == NULL) return; foreach(lc, g_cluster.clusterCommands) { - WDCommandData* clusterCommand = lfirst(lc); + WDCommandData *clusterCommand = lfirst(lc); + if (clusterCommand->commandStatus != COMMAND_IN_PROGRESS) { /* command needs to be cleaned up */ - finishedCommands = lappend(finishedCommands,clusterCommand); + finishedCommands = lappend(finishedCommands, clusterCommand); continue; } - for (i = 0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeResult = &clusterCommand->nodeResults[i]; + WDCommandNodeResult *nodeResult = &clusterCommand->nodeResults[i]; + if (nodeResult->cmdState == COMMAND_STATE_SEND_ERROR) { if (is_node_active_and_reachable(nodeResult->wdNode)) @@ -4069,22 +4250,25 @@ static void service_internal_command(void) /* delete the finished commands */ foreach(lc, finishedCommands) { - WDCommandData* clusterCommand = lfirst(lc); - g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands,clusterCommand); + WDCommandData *clusterCommand = lfirst(lc); + + g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands, clusterCommand); MemoryContextDelete(clusterCommand->memoryContext); } } /* remove the unreachable nodes from cluster */ -static void service_unreachable_nodes(void) +static void +service_unreachable_nodes(void) { - int i; + int i; struct timeval currTime; - gettimeofday(&currTime,NULL); - for (i = 0; i< g_cluster.remoteNodeCount; i++) + gettimeofday(&currTime, NULL); + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); if (is_node_active(wdNode) == false) continue; @@ -4094,10 +4278,10 @@ static void service_unreachable_nodes(void) /* check if we are waiting for reply from this node */ if (wdNode->last_sent_time.tv_sec > 0) { - if (WD_TIME_DIFF_SEC(currTime,wdNode->last_sent_time) >= MAX_SECS_WAIT_FOR_REPLY_FROM_NODE) + if (WD_TIME_DIFF_SEC(currTime, wdNode->last_sent_time) >= MAX_SECS_WAIT_FOR_REPLY_FROM_NODE) { ereport(LOG, - (errmsg("remote node \"%s\" is not replying..",wdNode->nodeName), + (errmsg("remote node \"%s\" is not replying..", wdNode->nodeName), errdetail("marking the node as lost"))); /* mark the node as lost */ watchdog_state_machine(WD_EVENT_REMOTE_NODE_LOST, wdNode, NULL, NULL); @@ -4107,23 +4291,24 @@ static void service_unreachable_nodes(void) else { ereport(LOG, - (errmsg("remote node \"%s\" is not reachable",wdNode->nodeName), + (errmsg("remote node \"%s\" is not reachable", wdNode->nodeName), errdetail("marking the node as lost"))); watchdog_state_machine(WD_EVENT_REMOTE_NODE_LOST, wdNode, NULL, NULL); } } } -static bool watchdog_internal_command_packet_processor(WatchdogNode* wdNode, WDPacketData* pkt) +static bool +watchdog_internal_command_packet_processor(WatchdogNode * wdNode, WDPacketData * pkt) { - int i; - WDCommandNodeResult* nodeResult = NULL; - WDCommandData* clusterCommand = get_wd_cluster_command_from_reply(pkt); + int i; + WDCommandNodeResult *nodeResult = NULL; + WDCommandData *clusterCommand = get_wd_cluster_command_from_reply(pkt); if (clusterCommand == NULL || clusterCommand->commandStatus != COMMAND_IN_PROGRESS) return false; - if (pkt->type != WD_ERROR_MESSAGE && + if (pkt->type != WD_ERROR_MESSAGE && pkt->type != WD_ACCEPT_MESSAGE && pkt->type != WD_REJECT_MESSAGE && pkt->type != WD_INFO_MESSAGE) @@ -4133,9 +4318,10 @@ static bool watchdog_internal_command_packet_processor(WatchdogNode* wdNode, WDP standard_packet_processor(wdNode, pkt); /* get the result node for */ - for (i = 0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeRes = &clusterCommand->nodeResults[i]; + WDCommandNodeResult *nodeRes = &clusterCommand->nodeResults[i]; + clear_command_node_result(nodeRes); if (nodeRes->wdNode == wdNode) { @@ -4145,12 +4331,12 @@ static bool watchdog_internal_command_packet_processor(WatchdogNode* wdNode, WDP } if (nodeResult == NULL) { - ereport(NOTICE,(errmsg("unable to find node result"))); + ereport(NOTICE, (errmsg("unable to find node result"))); return true; } ereport(DEBUG1, - (errmsg("Watchdog node \"%s\" has replied for command id %d",nodeResult->wdNode->nodeName,pkt->command_id))); + (errmsg("Watchdog node \"%s\" has replied for command id %d", nodeResult->wdNode->nodeName, pkt->command_id))); nodeResult->result_type = pkt->type; nodeResult->cmdState = COMMAND_STATE_REPLIED; @@ -4161,66 +4347,69 @@ static bool watchdog_internal_command_packet_processor(WatchdogNode* wdNode, WDP if (pkt->type == WD_REJECT_MESSAGE || pkt->type == WD_ERROR_MESSAGE) { ereport(DEBUG1, - (errmsg("command %c with command id %d is finished with COMMAND_FINISHED_NODE_REJECTED",pkt->type, pkt->command_id))); + (errmsg("command %c with command id %d is finished with COMMAND_FINISHED_NODE_REJECTED", pkt->type, pkt->command_id))); clusterCommand->commandStatus = COMMAND_FINISHED_NODE_REJECTED; } else { ereport(DEBUG1, - (errmsg("command %c with command id %d is finished with COMMAND_FINISHED_ALL_REPLIED",pkt->type, pkt->command_id))); + (errmsg("command %c with command id %d is finished with COMMAND_FINISHED_ALL_REPLIED", pkt->type, pkt->command_id))); clusterCommand->commandStatus = COMMAND_FINISHED_ALL_REPLIED; } watchdog_state_machine(WD_EVENT_COMMAND_FINISHED, wdNode, pkt, clusterCommand); - g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands,clusterCommand); + g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands, clusterCommand); MemoryContextDelete(clusterCommand->memoryContext); } else if (pkt->type == WD_REJECT_MESSAGE || pkt->type == WD_ERROR_MESSAGE) { /* Error or reject message by any node imidiately finishes the command */ ereport(DEBUG1, - (errmsg("command %c with command id %d is finished with COMMAND_FINISHED_NODE_REJECTED",pkt->type, pkt->command_id))); + (errmsg("command %c with command id %d is finished with COMMAND_FINISHED_NODE_REJECTED", pkt->type, pkt->command_id))); clusterCommand->commandStatus = COMMAND_FINISHED_NODE_REJECTED; watchdog_state_machine(WD_EVENT_COMMAND_FINISHED, wdNode, pkt, clusterCommand); - g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands,clusterCommand); + g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands, clusterCommand); MemoryContextDelete(clusterCommand->memoryContext); } - return true; /* do not process this packet further */ + return true; /* do not process this packet further */ } -static void check_for_current_command_timeout(void) +static void +check_for_current_command_timeout(void) { struct timeval currTime; - ListCell *lc; - List *finishedCommands = NULL; + ListCell *lc; + List *finishedCommands = NULL; if (g_cluster.clusterCommands == NULL) return; - gettimeofday(&currTime,NULL); + gettimeofday(&currTime, NULL); foreach(lc, g_cluster.clusterCommands) { - WDCommandData* clusterCommand = lfirst(lc); + WDCommandData *clusterCommand = lfirst(lc); + if (clusterCommand->commandStatus != COMMAND_IN_PROGRESS) { /* command needs to be cleaned up */ - finishedCommands = lappend(finishedCommands,clusterCommand); + finishedCommands = lappend(finishedCommands, clusterCommand); continue; } - if (WD_TIME_DIFF_SEC(currTime,clusterCommand->commandTime) >= clusterCommand->commandTimeoutSecs) + if (WD_TIME_DIFF_SEC(currTime, clusterCommand->commandTime) >= clusterCommand->commandTimeoutSecs) { clusterCommand->commandStatus = COMMAND_FINISHED_TIMEOUT; watchdog_state_machine(WD_EVENT_COMMAND_FINISHED, NULL, NULL, clusterCommand); - finishedCommands = lappend(finishedCommands,clusterCommand); + finishedCommands = lappend(finishedCommands, clusterCommand); } } /* delete the finished commands */ foreach(lc, finishedCommands) { - WDCommandData* clusterCommand = lfirst(lc); - g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands,clusterCommand); + WDCommandData *clusterCommand = lfirst(lc); + + g_cluster.clusterCommands = list_delete_ptr(g_cluster.clusterCommands, clusterCommand); MemoryContextDelete(clusterCommand->memoryContext); } } @@ -4230,10 +4419,11 @@ static void check_for_current_command_timeout(void) * If wdNode is NULL message is sent to all nodes * Returns the number of nodes the message is sent to */ -static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *pkt, int timeout_sec) +static int +issue_watchdog_internal_command(WatchdogNode * wdNode, WDPacketData * pkt, int timeout_sec) { - int i; - bool save_message = false; + int i; + bool save_message = false; WDCommandData *clusterCommand; MemoryContext oldCxt; @@ -4256,16 +4446,17 @@ static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *p allocate_resultNodes_in_command(clusterCommand); - if (wdNode == NULL) /* This is send to all */ + if (wdNode == NULL) /* This is send to all */ { - for (i = 0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeResult = &clusterCommand->nodeResults[i]; + WDCommandNodeResult *nodeResult = &clusterCommand->nodeResults[i]; + clear_command_node_result(nodeResult); if (is_node_active(nodeResult->wdNode) == false) { ereport(DEBUG2, - (errmsg("not sending watchdog internal command packet to DEAD %s",nodeResult->wdNode->nodeName))); + (errmsg("not sending watchdog internal command packet to DEAD %s", nodeResult->wdNode->nodeName))); /* Do not send to dead nodes */ nodeResult->cmdState = COMMAND_STATE_DO_NOT_SEND; } @@ -4274,7 +4465,7 @@ static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *p if (send_message_to_node(nodeResult->wdNode, pkt) == false) { ereport(DEBUG1, - (errmsg("failed to send watchdog internla command packet %s",nodeResult->wdNode->nodeName), + (errmsg("failed to send watchdog internla command packet %s", nodeResult->wdNode->nodeName), errdetail("saving the packet. will try to resend it if connection recovers"))); /* failed to send. May be try again later */ @@ -4291,10 +4482,12 @@ static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *p } if (wdNode) { - WDCommandNodeResult* nodeResult = NULL; - for (i = 0; i< g_cluster.remoteNodeCount; i++) + WDCommandNodeResult *nodeResult = NULL; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeRes = &clusterCommand->nodeResults[i]; + WDCommandNodeResult *nodeRes = &clusterCommand->nodeResults[i]; + clear_command_node_result(nodeRes); if (nodeRes->wdNode == wdNode) nodeResult = nodeRes; @@ -4318,12 +4511,12 @@ static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *p } if (save_message && pkt->len > 0) { - clusterCommand->commandPacket.data = MemoryContextAlloc(clusterCommand->memoryContext,pkt->len); - memcpy(clusterCommand->commandPacket.data,pkt->data,pkt->len); + clusterCommand->commandPacket.data = MemoryContextAlloc(clusterCommand->memoryContext, pkt->len); + memcpy(clusterCommand->commandPacket.data, pkt->data, pkt->len); clusterCommand->commandPacket.len = pkt->len; } ereport(DEBUG2, - (errmsg("new cluster command %c issued with command id %d",pkt->type,pkt->command_id))); + (errmsg("new cluster command %c issued with command id %d", pkt->type, pkt->command_id))); oldCxt = MemoryContextSwitchTo(TopMemoryContext); g_cluster.clusterCommands = lappend(g_cluster.clusterCommands, clusterCommand); @@ -4332,21 +4525,24 @@ static int issue_watchdog_internal_command(WatchdogNode* wdNode, WDPacketData *p return clusterCommand->commandSendToCount; } -static bool service_lost_connections(void) +static bool +service_lost_connections(void) { - int i; + int i; struct timeval currTime; - bool ret = false; - gettimeofday(&currTime,NULL); - for (i = 0; i< g_cluster.remoteNodeCount; i++) + bool ret = false; + + gettimeofday(&currTime, NULL); + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->state == WD_SHUTDOWN || wdNode->state == WD_DEAD) continue; if (is_socket_connection_connected(&wdNode->client_socket) == false) { - if (WD_TIME_DIFF_SEC(currTime,wdNode->client_socket.tv) <= MIN_SECS_CONNECTION_RETRY) + if (WD_TIME_DIFF_SEC(currTime, wdNode->client_socket.tv) <= MIN_SECS_CONNECTION_RETRY) continue; if (wdNode->client_socket.sock_state != WD_SOCK_WAITING_FOR_CONNECT) @@ -4355,7 +4551,7 @@ static bool service_lost_connections(void) if (wdNode->client_socket.sock_state == WD_SOCK_CONNECTED) { ereport(LOG, - (errmsg("connection to the remote node \"%s\" is restored",wdNode->nodeName))); + (errmsg("connection to the remote node \"%s\" is restored", wdNode->nodeName))); watchdog_state_machine(WD_EVENT_NEW_OUTBOUND_CONNECTION, wdNode, NULL, NULL); ret = true; } @@ -4370,13 +4566,16 @@ static bool service_lost_connections(void) * All node states count towards the cluster participating nodes * except the dead and lost nodes. */ -static int get_cluster_node_count(void) +static int +get_cluster_node_count(void) { - int i; - int count = 0; - for (i = 0; i< g_cluster.remoteNodeCount; i++) + int i; + int count = 0; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->state == WD_DEAD || wdNode->state == WD_LOST || wdNode->state == WD_SHUTDOWN) continue; count++; @@ -4384,9 +4583,10 @@ static int get_cluster_node_count(void) return count; } -static WDPacketData* get_message_of_type(char type, WDPacketData* replyFor) +static WDPacketData * get_message_of_type(char type, WDPacketData * replyFor) { WDPacketData *pkt = NULL; + switch (type) { case WD_INFO_MESSAGE: @@ -4396,7 +4596,7 @@ static WDPacketData* get_message_of_type(char type, WDPacketData* replyFor) pkt = get_addnode_message(); break; case WD_IAM_COORDINATOR_MESSAGE: - pkt = get_beacon_message(WD_IAM_COORDINATOR_MESSAGE,replyFor); + pkt = get_beacon_message(WD_IAM_COORDINATOR_MESSAGE, replyFor); break; case WD_FAILOVER_START: @@ -4412,16 +4612,18 @@ static WDPacketData* get_message_of_type(char type, WDPacketData* replyFor) pkt = get_minimum_message(type, replyFor); break; default: - ereport(LOG,(errmsg("invalid message type %c",type))); + ereport(LOG, (errmsg("invalid message type %c", type))); break; } return pkt; } -static int send_message_of_type(WatchdogNode* wdNode, char type, WDPacketData* replyFor) +static int +send_message_of_type(WatchdogNode * wdNode, char type, WDPacketData * replyFor) { - int ret = -1; + int ret = -1; WDPacketData *pkt = get_message_of_type(type, replyFor); + if (pkt) { ret = send_message(wdNode, pkt); @@ -4430,10 +4632,12 @@ static int send_message_of_type(WatchdogNode* wdNode, char type, WDPacketData* r return ret; } -static int send_cluster_command(WatchdogNode* wdNode, char type, int timeout_sec) +static int +send_cluster_command(WatchdogNode * wdNode, char type, int timeout_sec) { - int ret = -1; + int ret = -1; WDPacketData *pkt = get_message_of_type(type, NULL); + if (pkt) { ret = issue_watchdog_internal_command(wdNode, pkt, timeout_sec); @@ -4442,24 +4646,29 @@ static int send_cluster_command(WatchdogNode* wdNode, char type, int timeout_sec return ret; } -static bool reply_with_minimal_message(WatchdogNode* wdNode, char type, WDPacketData* replyFor) +static bool +reply_with_minimal_message(WatchdogNode * wdNode, char type, WDPacketData * replyFor) { - WDPacketData *pkt = get_minimum_message(type,replyFor); - int ret = send_message(wdNode, pkt); + WDPacketData *pkt = get_minimum_message(type, replyFor); + int ret = send_message(wdNode, pkt); + free_packet(pkt); return ret; } -static bool send_cluster_service_message(WatchdogNode* wdNode, WDPacketData* replyFor, char message) +static bool +send_cluster_service_message(WatchdogNode * wdNode, WDPacketData * replyFor, char message) { return reply_with_message(wdNode, WD_CLUSTER_SERVICE_MESSAGE, &message, 1, replyFor); } -static bool reply_with_message(WatchdogNode* wdNode, char type, char* data, int data_len, WDPacketData* replyFor) +static bool +reply_with_message(WatchdogNode * wdNode, char type, char *data, int data_len, WDPacketData * replyFor) { WDPacketData wdPacket; - int ret; + int ret; + init_wd_packet(&wdPacket); set_message_type(&wdPacket, type); @@ -4478,7 +4687,8 @@ static inline WD_STATES get_local_node_state(void) return g_cluster.localNode->state; } -static inline bool is_local_node_true_master(void) +static inline bool +is_local_node_true_master(void) { return (get_local_node_state() == WD_COORDINATOR && WD_MASTER_NODE == g_cluster.localNode); } @@ -4487,22 +4697,23 @@ static inline bool is_local_node_true_master(void) * returns true if no message is swollowed by the * processor and no further action is required */ -static bool wd_commands_packet_processor(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt) +static bool +wd_commands_packet_processor(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt) { - WDCommandData* ipcCommand; - + WDCommandData *ipcCommand; + if (event != WD_EVENT_PACKET_RCV) return false; if (pkt == NULL) return false; if (pkt->type == WD_FAILOVER_LOCKING_REQUEST || - pkt->type == WD_REMOTE_FAILOVER_REQUEST ) + pkt->type == WD_REMOTE_FAILOVER_REQUEST) { /* Node is using the older version of Pgpool-II */ ereport(WARNING, - (errmsg("node \"%s\" is using the older version of Pgpool-II",wdNode->nodeName))); - send_cluster_service_message(wdNode,pkt,CLUSTER_NODE_INVALID_VERSION); + (errmsg("node \"%s\" is using the older version of Pgpool-II", wdNode->nodeName))); + send_cluster_service_message(wdNode, pkt, CLUSTER_NODE_INVALID_VERSION); return true; } @@ -4528,7 +4739,7 @@ static bool wd_commands_packet_processor(WD_EVENTS event, WatchdogNode* wdNode, (errmsg("failed to forward data message to IPC command socket"))); cleanUpIPCCommand(ipcCommand); - return true; /* do not process this packet further */ + return true; /* do not process this packet further */ } return false; } @@ -4543,11 +4754,12 @@ static bool wd_commands_packet_processor(WD_EVENTS event, WatchdogNode* wdNode, if (write_ipc_command_with_result_data(ipcCommand, WD_IPC_CMD_RESULT_OK, pkt->data, pkt->len) == false) ereport(LOG, (errmsg("failed to forward data message to IPC command socket"))); + /* * ok we are done, delete this command */ cleanUpIPCCommand(ipcCommand); - return true; /* do not process this packet further */ + return true; /* do not process this packet further */ } else if (pkt->type == WD_ACCEPT_MESSAGE || @@ -4578,11 +4790,12 @@ static bool wd_commands_packet_processor(WD_EVENTS event, WatchdogNode* wdNode, } -static void update_interface_status(void) +static void +update_interface_status(void) { - struct ifaddrs *ifAddrStruct=NULL; - struct ifaddrs *ifa=NULL; - ListCell *lc; + struct ifaddrs *ifAddrStruct = NULL; + struct ifaddrs *ifa = NULL; + ListCell *lc; if (g_cluster.wdInterfaceToMonitor == NULL) return; @@ -4591,14 +4804,15 @@ static void update_interface_status(void) for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { ereport(DEBUG1, - (errmsg("network interface %s having flags %d",ifa->ifa_name,ifa->ifa_flags))); + (errmsg("network interface %s having flags %d", ifa->ifa_name, ifa->ifa_flags))); if (!strncasecmp("lo", ifa->ifa_name, 2)) - continue; /* We do not need loop back addresses */ + continue; /* We do not need loop back addresses */ foreach(lc, g_cluster.wdInterfaceToMonitor) { - WDInterfaceStatus* if_status = lfirst(lc); + WDInterfaceStatus *if_status = lfirst(lc); + if (!strcasecmp(if_status->if_name, ifa->ifa_name)) { if_status->if_up = is_interface_up(ifa); @@ -4607,14 +4821,16 @@ static void update_interface_status(void) } } - if (ifAddrStruct!=NULL) + if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct); } -static bool any_interface_available(void) +static bool +any_interface_available(void) { - ListCell *lc; + ListCell *lc; + update_interface_status(); /* if interface monitoring is disabled we are good */ if (g_cluster.wdInterfaceToMonitor == NULL) @@ -4622,23 +4838,25 @@ static bool any_interface_available(void) foreach(lc, g_cluster.wdInterfaceToMonitor) { - WDInterfaceStatus* if_status = lfirst(lc); + WDInterfaceStatus *if_status = lfirst(lc); + if (if_status->if_up) { ereport(DEBUG1, - (errmsg("network interface \"%s\" is up and we can continue",if_status->if_name))); + (errmsg("network interface \"%s\" is up and we can continue", if_status->if_name))); return true; } } return false; } -static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { ereport(DEBUG1, (errmsg("STATE MACHINE INVOKED WITH EVENT = %s Current State = %s", wd_event_name[event], wd_state_names[get_local_node_state()]))); - + if (event == WD_EVENT_REMOTE_NODE_LOST) { /* close all socket connections to the node */ @@ -4648,13 +4866,13 @@ static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacke if (wdNode->state == WD_SHUTDOWN) { ereport(LOG, - (errmsg("remote node \"%s\" is shutting down",wdNode->nodeName))); + (errmsg("remote node \"%s\" is shutting down", wdNode->nodeName))); } else { wdNode->state = WD_LOST; ereport(LOG, - (errmsg("remote node \"%s\" is lost",wdNode->nodeName))); + (errmsg("remote node \"%s\" is lost", wdNode->nodeName))); } if (wdNode == WD_MASTER_NODE) { @@ -4670,8 +4888,8 @@ static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacke } else if (event == WD_EVENT_PACKET_RCV) { - print_packet_node_info(pkt,wdNode, false); - /* update the last receiv time*/ + print_packet_node_info(pkt, wdNode, false); + /* update the last receiv time */ gettimeofday(&wdNode->last_rcv_time, NULL); if (pkt->type == WD_INFO_MESSAGE) @@ -4685,57 +4903,59 @@ static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacke return watchdog_state_machine(WD_EVENT_REMOTE_NODE_LOST, wdNode, NULL, NULL); } - if (watchdog_internal_command_packet_processor(wdNode,pkt) == true) + if (watchdog_internal_command_packet_processor(wdNode, pkt) == true) { return 0; } } else if (event == WD_EVENT_NEW_OUTBOUND_CONNECTION) { - WDPacketData* addPkt = get_addnode_message(); + WDPacketData *addPkt = get_addnode_message(); + send_message(wdNode, addPkt); free_packet(addPkt); } else if (event == WD_EVENT_NW_IP_IS_REMOVED || event == WD_EVENT_NW_LINK_IS_INACTIVE) { - List* local_addresses; + List *local_addresses; /* check if we have an active link */ if (any_interface_available() == false) { ereport(WARNING, - (errmsg("network event has occured and all monitored interfaces are down"), + (errmsg("network event has occured and all monitored interfaces are down"), errdetail("changing the state to in network trouble"))); - + set_state(WD_IN_NW_TROUBLE); - + } /* check if all IP addresses are lost */ local_addresses = get_all_local_ips(); if (local_addresses == NULL) { /* - * We have lost all IP addresses - * we are in network trouble. Just move to - * in network trouble state + * We have lost all IP addresses we are in network trouble. Just + * move to in network trouble state */ ereport(WARNING, - (errmsg("network IP is removed and system has no IP is assigned"), + (errmsg("network IP is removed and system has no IP is assigned"), errdetail("changing the state to in network trouble"))); set_state(WD_IN_NW_TROUBLE); } else { - ListCell *lc; + ListCell *lc; + ereport(DEBUG1, - (errmsg("network IP is removed but system still has a valid IP is assigned"))); + (errmsg("network IP is removed but system still has a valid IP is assigned"))); foreach(lc, local_addresses) { - char* ip = lfirst(lc); + char *ip = lfirst(lc); + ereport(DEBUG1, - (errmsg("IP = %s",ip?ip:"NULL"))); + (errmsg("IP = %s", ip ? ip : "NULL"))); } } } @@ -4743,7 +4963,7 @@ static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacke else if (event == WD_EVENT_LOCAL_NODE_LOST) { ereport(WARNING, - (errmsg("watchdog lifecheck reported, we are disconnected from the network"), + (errmsg("watchdog lifecheck reported, we are disconnected from the network"), errdetail("changing the state to LOST"))); set_state(WD_LOST); } @@ -4785,7 +5005,7 @@ static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacke set_state(WD_LOADING); break; } - + return 0; } @@ -4795,28 +5015,31 @@ static int watchdog_state_machine(WD_EVENTS event, WatchdogNode* wdNode, WDPacke * nodes. * Wait for 4 seconds if some node rejects us. */ -static int watchdog_state_machine_loading(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_loading(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { case WD_EVENT_WD_STATE_CHANGED: - { - int i; - WDPacketData* addPkt = get_addnode_message(); - /* set the status to ADD_MESSAGE_SEND by hand */ - for (i = 0; i< g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdTmpNode; - wdTmpNode = &(g_cluster.remoteNodes[i]); - if (wdTmpNode->client_socket.sock_state == WD_SOCK_CONNECTED && wdTmpNode->state == WD_DEAD) + int i; + WDPacketData *addPkt = get_addnode_message(); + + /* set the status to ADD_MESSAGE_SEND by hand */ + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - if (send_message(wdTmpNode, addPkt)) - wdTmpNode->state = WD_ADD_MESSAGE_SENT; + WatchdogNode *wdTmpNode; + + wdTmpNode = &(g_cluster.remoteNodes[i]); + if (wdTmpNode->client_socket.sock_state == WD_SOCK_CONNECTED && wdTmpNode->state == WD_DEAD) + { + if (send_message(wdTmpNode, addPkt)) + wdTmpNode->state = WD_ADD_MESSAGE_SENT; + } } + free_packet(addPkt); + set_timeout(MAX_SECS_WAIT_FOR_REPLY_FROM_NODE); } - free_packet(addPkt); - set_timeout(MAX_SECS_WAIT_FOR_REPLY_FROM_NODE); - } break; case WD_EVENT_TIMEOUT: @@ -4824,67 +5047,71 @@ static int watchdog_state_machine_loading(WD_EVENTS event, WatchdogNode* wdNode, break; case WD_EVENT_PACKET_RCV: - { - switch (pkt->type) { - case WD_STAND_FOR_COORDINATOR_MESSAGE: + switch (pkt->type) { - /* We are loading but a note is already contesting for coordinator node - * well we can ignore it but then this could eventually mean a lower priority - * node can became a coordinator node. - * So check the priority of the node in stand for coordinator state - */ - if (g_cluster.localNode->wd_priority > wdNode->wd_priority) - { - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - set_state(WD_STAND_FOR_COORDINATOR); - } - else - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - set_state(WD_PARTICIPATE_IN_ELECTION); - } - } - break; + case WD_STAND_FOR_COORDINATOR_MESSAGE: + { + /* + * We are loading but a note is already contesting + * for coordinator node well we can ignore it but + * then this could eventually mean a lower + * priority node can became a coordinator node. So + * check the priority of the node in stand for + * coordinator state + */ + if (g_cluster.localNode->wd_priority > wdNode->wd_priority) + { + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + set_state(WD_STAND_FOR_COORDINATOR); + } + else + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + set_state(WD_PARTICIPATE_IN_ELECTION); + } + } + break; - case WD_INFO_MESSAGE: - { - int i; - bool all_replied = true; - for (i = 0; i< g_cluster.remoteNodeCount; i++) - { - wdNode = &(g_cluster.remoteNodes[i]); - if (wdNode->state == WD_ADD_MESSAGE_SENT) + case WD_INFO_MESSAGE: { - all_replied = false; - break; + int i; + bool all_replied = true; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) + { + wdNode = &(g_cluster.remoteNodes[i]); + if (wdNode->state == WD_ADD_MESSAGE_SENT) + { + all_replied = false; + break; + } + } + if (all_replied) + { + /* + * we are already connected to all configured + * nodes Just move to initializing state + */ + set_state(WD_INITIALIZING); + } } - } - if (all_replied) - { - /* - * we are already connected to all configured nodes - * Just move to initializing state - */ - set_state(WD_INITIALIZING); - } - } - break; + break; - case WD_REJECT_MESSAGE: - if (wdNode->state == WD_ADD_MESSAGE_SENT || wdNode->state == WD_DEAD) - ereport(FATAL, - (return_code(POOL_EXIT_FATAL), - errmsg("Add to watchdog cluster request is rejected by node \"%s:%d\"",wdNode->hostname,wdNode->wd_port), - errhint("check the watchdog configurations."))); - break; - default: - standard_packet_processor(wdNode, pkt); - break; + case WD_REJECT_MESSAGE: + if (wdNode->state == WD_ADD_MESSAGE_SENT || wdNode->state == WD_DEAD) + ereport(FATAL, + (return_code(POOL_EXIT_FATAL), + errmsg("Add to watchdog cluster request is rejected by node \"%s:%d\"", wdNode->hostname, wdNode->wd_port), + errhint("check the watchdog configurations."))); + break; + default: + standard_packet_processor(wdNode, pkt); + break; + } } - } break; - default: + default: break; } return 0; @@ -4896,7 +5123,8 @@ static int watchdog_state_machine_loading(WD_EVENTS event, WatchdogNode* wdNode, * initialization state. moving to this state from loading does not make * much sence as at loading time we already have updated node informations */ -static int watchdog_state_machine_joining(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_joining(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { @@ -4912,52 +5140,55 @@ static int watchdog_state_machine_joining(WD_EVENTS event, WatchdogNode* wdNode, break; case WD_EVENT_COMMAND_FINISHED: - { - if (clusterCommand->commandPacket.type == WD_REQ_INFO_MESSAGE) - set_state(WD_INITIALIZING); - } + { + if (clusterCommand->commandPacket.type == WD_REQ_INFO_MESSAGE) + set_state(WD_INITIALIZING); + } break; case WD_EVENT_PACKET_RCV: - { - switch (pkt->type) { - case WD_REJECT_MESSAGE: - if (wdNode->state == WD_ADD_MESSAGE_SENT) - ereport(FATAL, - (return_code(POOL_EXIT_FATAL), - errmsg("add to watchdog cluster request is rejected by node \"%s:%d\"",wdNode->hostname,wdNode->wd_port), - errhint("check the watchdog configurations."))); - break; - - case WD_STAND_FOR_COORDINATOR_MESSAGE: + switch (pkt->type) { - /* We are loading but a node is already contesting for coordinator node - * well we can ignore it but then this could eventually mean a lower priority - * node can became a coordinator node. - * So check the priority of the node in stand for coordinator state - */ - if (g_cluster.localNode->wd_priority > wdNode->wd_priority) - { - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - set_state(WD_STAND_FOR_COORDINATOR); - } - else - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - set_state(WD_PARTICIPATE_IN_ELECTION); - } - } - break; + case WD_REJECT_MESSAGE: + if (wdNode->state == WD_ADD_MESSAGE_SENT) + ereport(FATAL, + (return_code(POOL_EXIT_FATAL), + errmsg("add to watchdog cluster request is rejected by node \"%s:%d\"", wdNode->hostname, wdNode->wd_port), + errhint("check the watchdog configurations."))); + break; - default: - standard_packet_processor(wdNode, pkt); - break; + case WD_STAND_FOR_COORDINATOR_MESSAGE: + { + /* + * We are loading but a node is already contesting + * for coordinator node well we can ignore it but + * then this could eventually mean a lower + * priority node can became a coordinator node. So + * check the priority of the node in stand for + * coordinator state + */ + if (g_cluster.localNode->wd_priority > wdNode->wd_priority) + { + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + set_state(WD_STAND_FOR_COORDINATOR); + } + else + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + set_state(WD_PARTICIPATE_IN_ELECTION); + } + } + break; + + default: + standard_packet_processor(wdNode, pkt); + break; + } } - } break; - - default: + + default: break; } @@ -4969,7 +5200,8 @@ static int watchdog_state_machine_joining(WD_EVENTS event, WatchdogNode* wdNode, * sends any cluster command. */ -static int watchdog_state_machine_initializing(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_initializing(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { @@ -4979,66 +5211,68 @@ static int watchdog_state_machine_initializing(WD_EVENTS event, WatchdogNode* wd break; case WD_EVENT_TIMEOUT: - { - /* - * If master node exists in cluser, Join it - * otherwise try becoming a master - */ - if (WD_MASTER_NODE) { /* - * we found the coordinator node in network. - * Just join the network + * If master node exists in cluser, Join it otherwise try + * becoming a master */ - set_state(WD_STANDBY); - } - else if (get_cluster_node_count() == 0) - { - ereport(LOG, - (errmsg("I am the only alive node in the watchdog cluster"), - errhint("skipping stand for coordinator state"))); + if (WD_MASTER_NODE) + { + /* + * we found the coordinator node in network. Just join the + * network + */ + set_state(WD_STANDBY); + } + else if (get_cluster_node_count() == 0) + { + ereport(LOG, + (errmsg("I am the only alive node in the watchdog cluster"), + errhint("skipping stand for coordinator state"))); - /* - * I am the alone node in the cluster at the moment - * skip the intermediate steps and jump to the coordinator - * state - */ - set_state(WD_COORDINATOR); - } - else - { - int i; - for (i=0; i< g_cluster.remoteNodeCount; i++) + /* + * I am the alone node in the cluster at the moment skip + * the intermediate steps and jump to the coordinator + * state + */ + set_state(WD_COORDINATOR); + } + else { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); - if (wdNode->state == WD_STAND_FOR_COORDINATOR) + int i; + + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - set_state(WD_PARTICIPATE_IN_ELECTION); - return 0; + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + + if (wdNode->state == WD_STAND_FOR_COORDINATOR) + { + set_state(WD_PARTICIPATE_IN_ELECTION); + return 0; + } } + /* stand for coordinator */ + set_state(WD_STAND_FOR_COORDINATOR); } - /* stand for coordinator */ - set_state(WD_STAND_FOR_COORDINATOR); } - } break; - + case WD_EVENT_PACKET_RCV: - { - switch (pkt->type) { - case WD_REJECT_MESSAGE: - if (wdNode->state == WD_ADD_MESSAGE_SENT) - ereport(FATAL, - (return_code(POOL_EXIT_FATAL), - errmsg("Add to watchdog cluster request is rejected by node \"%s:%d\"",wdNode->hostname,wdNode->wd_port), - errhint("check the watchdog configurations."))); - break; - default: - standard_packet_processor(wdNode, pkt); - break; + switch (pkt->type) + { + case WD_REJECT_MESSAGE: + if (wdNode->state == WD_ADD_MESSAGE_SENT) + ereport(FATAL, + (return_code(POOL_EXIT_FATAL), + errmsg("Add to watchdog cluster request is rejected by node \"%s:%d\"", wdNode->hostname, wdNode->wd_port), + errhint("check the watchdog configurations."))); + break; + default: + standard_packet_processor(wdNode, pkt); + break; + } } - } break; @@ -5048,52 +5282,53 @@ static int watchdog_state_machine_initializing(WD_EVENTS event, WatchdogNode* wd return 0; } -static int watchdog_state_machine_standForCord(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_standForCord(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { case WD_EVENT_WD_STATE_CHANGED: send_cluster_command(NULL, WD_STAND_FOR_COORDINATOR_MESSAGE, 4); - /* wait for 5 seconds if someone rejects us*/ + /* wait for 5 seconds if someone rejects us */ set_timeout(MAX_SECS_WAIT_FOR_REPLY_FROM_NODE); break; case WD_EVENT_COMMAND_FINISHED: - { - if (clusterCommand->commandPacket.type == WD_STAND_FOR_COORDINATOR_MESSAGE) { - if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED || - clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + if (clusterCommand->commandPacket.type == WD_STAND_FOR_COORDINATOR_MESSAGE) { + if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED || + clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + { set_state(WD_COORDINATOR); - } - else - { - /* command finished with an error */ - if (pkt) + } + else { - if (pkt->type == WD_ERROR_MESSAGE) + /* command finished with an error */ + if (pkt) { - ereport(LOG, - (errmsg("our stand for coordinator request is rejected by node \"%s\"",wdNode->nodeName))); - set_state(WD_JOINING); + if (pkt->type == WD_ERROR_MESSAGE) + { + ereport(LOG, + (errmsg("our stand for coordinator request is rejected by node \"%s\"", wdNode->nodeName))); + set_state(WD_JOINING); + } + else if (pkt->type == WD_REJECT_MESSAGE) + { + ereport(LOG, + (errmsg("our stand for coordinator request is rejected by node \"%s\"", wdNode->nodeName))); + set_state(WD_PARTICIPATE_IN_ELECTION); + } } - else if (pkt->type == WD_REJECT_MESSAGE) + else { ereport(LOG, - (errmsg("our stand for coordinator request is rejected by node \"%s\"",wdNode->nodeName))); - set_state(WD_PARTICIPATE_IN_ELECTION); + (errmsg("our stand for coordinator request is rejected by node \"%s\"", wdNode->nodeName))); + set_state(WD_JOINING); } } - else - { - ereport(LOG, - (errmsg("our stand for coordinator request is rejected by node \"%s\"",wdNode->nodeName))); - set_state(WD_JOINING); - } } } - } break; case WD_EVENT_TIMEOUT: @@ -5101,61 +5336,64 @@ static int watchdog_state_machine_standForCord(WD_EVENTS event, WatchdogNode* wd break; case WD_EVENT_PACKET_RCV: - { - switch (pkt->type) { - case WD_STAND_FOR_COORDINATOR_MESSAGE: - /* decide on base of priority */ - if (g_cluster.localNode->wd_priority > wdNode->wd_priority) - { - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - } - else if (g_cluster.localNode->wd_priority == wdNode->wd_priority) - { - /* decide on base of starting time */ - if (g_cluster.localNode->startup_time.tv_sec <= wdNode->startup_time.tv_sec)/* I am older */ + switch (pkt->type) + { + case WD_STAND_FOR_COORDINATOR_MESSAGE: + /* decide on base of priority */ + if (g_cluster.localNode->wd_priority > wdNode->wd_priority) { reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); } + else if (g_cluster.localNode->wd_priority == wdNode->wd_priority) + { + /* decide on base of starting time */ + if (g_cluster.localNode->startup_time.tv_sec <= wdNode->startup_time.tv_sec) /* I am older */ + { + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + } + else + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + set_state(WD_PARTICIPATE_IN_ELECTION); + } + } else { reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); set_state(WD_PARTICIPATE_IN_ELECTION); } - } - else - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - set_state(WD_PARTICIPATE_IN_ELECTION); - } - break; + break; - case WD_DECLARE_COORDINATOR_MESSAGE: - { - /* meanwhile someone has declared itself coordinator */ - if (g_cluster.localNode->wd_priority > wdNode->wd_priority) - { - ereport(LOG, - (errmsg("rejecting the declare coordinator request from node \"%s\"",wdNode->nodeName), - errdetail("my wd_priority [%d] is higher than the requesting node's priority [%d]",g_cluster.localNode->wd_priority,wdNode->wd_priority))); - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - } - else - { - ereport(LOG, - (errmsg("node \"%s\" has declared itself as a coordinator",wdNode->nodeName) )); - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - set_state(WD_JOINING); - } + case WD_DECLARE_COORDINATOR_MESSAGE: + { + /* + * meanwhile someone has declared itself + * coordinator + */ + if (g_cluster.localNode->wd_priority > wdNode->wd_priority) + { + ereport(LOG, + (errmsg("rejecting the declare coordinator request from node \"%s\"", wdNode->nodeName), + errdetail("my wd_priority [%d] is higher than the requesting node's priority [%d]", g_cluster.localNode->wd_priority, wdNode->wd_priority))); + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + } + else + { + ereport(LOG, + (errmsg("node \"%s\" has declared itself as a coordinator", wdNode->nodeName))); + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + set_state(WD_JOINING); + } + } + break; + default: + standard_packet_processor(wdNode, pkt); + break; } - break; - default: - standard_packet_processor(wdNode, pkt); - break; } - } break; - + default: break; } @@ -5167,266 +5405,283 @@ static int watchdog_state_machine_standForCord(WD_EVENTS event, WatchdogNode* wd * The function handels all the event received when the local * node is the master/coordinator node. */ -static int watchdog_state_machine_coordinator(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_coordinator(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { case WD_EVENT_WD_STATE_CHANGED: - { - int i; - send_cluster_command(NULL, WD_DECLARE_COORDINATOR_MESSAGE, 4); - set_timeout(MAX_SECS_WAIT_FOR_REPLY_FROM_NODE); - ereport(LOG, - (errmsg("I am announcing my self as master/coordinator watchdog node"))); - - for (i=0; i< g_cluster.remoteNodeCount; i++) { - WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); - ereport(DEBUG2, - (errmsg("printing all remote node information"))); - print_watchdog_node_info(wdNode); + int i; + + send_cluster_command(NULL, WD_DECLARE_COORDINATOR_MESSAGE, 4); + set_timeout(MAX_SECS_WAIT_FOR_REPLY_FROM_NODE); + ereport(LOG, + (errmsg("I am announcing my self as master/coordinator watchdog node"))); + + for (i = 0; i < g_cluster.remoteNodeCount; i++) + { + WatchdogNode *wdNode = &(g_cluster.remoteNodes[i]); + + ereport(DEBUG2, + (errmsg("printing all remote node information"))); + print_watchdog_node_info(wdNode); + } } - } break; case WD_EVENT_COMMAND_FINISHED: - { - if (clusterCommand->commandPacket.type == WD_DECLARE_COORDINATOR_MESSAGE) { - if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED || - clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + if (clusterCommand->commandPacket.type == WD_DECLARE_COORDINATOR_MESSAGE) { - update_quorum_status(); + if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED || + clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + { + update_quorum_status(); - ereport(DEBUG1, - (errmsg("declare coordinator command finished with status:[%s]", - clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED? - "ALL NODES REPLIED": - "COMMAND TIMEED OUT"), - errdetail("The command was sent to %d nodes and %d nodes replied to it", - clusterCommand->commandSendToCount, - clusterCommand->commandReplyFromCount - ))); + ereport(DEBUG1, + (errmsg("declare coordinator command finished with status:[%s]", + clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED ? + "ALL NODES REPLIED" : + "COMMAND TIMEED OUT"), + errdetail("The command was sent to %d nodes and %d nodes replied to it", + clusterCommand->commandSendToCount, + clusterCommand->commandReplyFromCount + ))); - ereport(LOG, - (errmsg("I am the cluster leader node"), - errdetail("our declare coordinator message is accepted by all nodes"))); + ereport(LOG, + (errmsg("I am the cluster leader node"), + errdetail("our declare coordinator message is accepted by all nodes"))); - set_cluster_master_node(g_cluster.localNode); - register_watchdog_state_change_interupt(); + set_cluster_master_node(g_cluster.localNode); + register_watchdog_state_change_interupt(); - /* - * Check if the quorum is present then start the escalation process - * otherwise keep in the coordinator state and wait for the quorum - */ - if (g_cluster.quorum_status == -1) - { - ereport(LOG, - (errmsg("I am the cluster leader node but we do not have enough nodes in cluster"), - errdetail("waiting for the quorum to start escalation process"))); + /* + * Check if the quorum is present then start the + * escalation process otherwise keep in the + * coordinator state and wait for the quorum + */ + if (g_cluster.quorum_status == -1) + { + ereport(LOG, + (errmsg("I am the cluster leader node but we do not have enough nodes in cluster"), + errdetail("waiting for the quorum to start escalation process"))); + } + else + { + ereport(LOG, + (errmsg("I am the cluster leader node. Starting escalation process"))); + start_escalated_node(); + } } else { - ereport(LOG, - (errmsg("I am the cluster leader node. Starting escalation process"))); - start_escalated_node(); + /* command is finished but because of error */ + ereport(NOTICE, + (errmsg("possible split brain scenario detected by \"%s\" node", wdNode->nodeName), + (errdetail("re-initializing cluster")))); + set_state(WD_JOINING); } } - else - { - /* command is finished but because of error */ - ereport(NOTICE, - (errmsg("possible split brain scenario detected by \"%s\" node", wdNode->nodeName), - (errdetail("re-initializing cluster")))); - set_state(WD_JOINING); - } - } - - else if (clusterCommand->commandPacket.type == WD_IAM_COORDINATOR_MESSAGE) - { - if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED) - { - ereport(DEBUG1, - (errmsg("I am the cluster leader node command finished with status:[ALL NODES REPLIED]"), - errdetail("The command was sent to %d nodes and %d nodes replied to it", - clusterCommand->commandSendToCount, - clusterCommand->commandReplyFromCount - ))); - } - else if (clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) - { - ereport(DEBUG1, - (errmsg("I am the cluster leader node command finished with status:[COMMAND TIMEED OUT] which is success"), - errdetail("The command was sent to %d nodes and %d nodes replied to it", - clusterCommand->commandSendToCount, - clusterCommand->commandReplyFromCount - ))); - } - else if (clusterCommand->commandStatus == COMMAND_FINISHED_NODE_REJECTED) + + else if (clusterCommand->commandPacket.type == WD_IAM_COORDINATOR_MESSAGE) { - /* one of the node rejected out I am coordinator message */ - ereport(LOG, - (errmsg("possible split brain, \"%s\" node has rejected our coordinator beacon", wdNode->nodeName), - (errdetail("removing the node from out standby list")))); + if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED) + { + ereport(DEBUG1, + (errmsg("I am the cluster leader node command finished with status:[ALL NODES REPLIED]"), + errdetail("The command was sent to %d nodes and %d nodes replied to it", + clusterCommand->commandSendToCount, + clusterCommand->commandReplyFromCount + ))); + } + else if (clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + { + ereport(DEBUG1, + (errmsg("I am the cluster leader node command finished with status:[COMMAND TIMEED OUT] which is success"), + errdetail("The command was sent to %d nodes and %d nodes replied to it", + clusterCommand->commandSendToCount, + clusterCommand->commandReplyFromCount + ))); + } + else if (clusterCommand->commandStatus == COMMAND_FINISHED_NODE_REJECTED) + { + /* + * one of the node rejected out I am coordinator + * message + */ + ereport(LOG, + (errmsg("possible split brain, \"%s\" node has rejected our coordinator beacon", wdNode->nodeName), + (errdetail("removing the node from out standby list")))); - standby_node_left_cluster(wdNode); + standby_node_left_cluster(wdNode); + } } } - } break; case WD_EVENT_CLUSTER_QUORUM_CHANGED: - { - /* make sure we are accepted as master*/ - if (WD_MASTER_NODE == g_cluster.localNode) { - if (g_cluster.quorum_status == -1) - { - ereport(LOG, - (errmsg("We have lost the quorum"))); - /* - * We have lost the quorum, stay as a master node but - * perform de-escalation. As keeping the VIP may result in - * split-brain - */ - resign_from_escalated_node(); - } - else if (g_cluster.quorum_status >= 0) + /* make sure we are accepted as master */ + if (WD_MASTER_NODE == g_cluster.localNode) { - if (g_cluster.localNode->escalated == false) + if (g_cluster.quorum_status == -1) { ereport(LOG, - (errmsg("quorum found"), - errdetail("starting escalation process"))); - start_escalated_node(); + (errmsg("We have lost the quorum"))); + + /* + * We have lost the quorum, stay as a master node but + * perform de-escalation. As keeping the VIP may + * result in split-brain + */ + resign_from_escalated_node(); + } + else if (g_cluster.quorum_status >= 0) + { + if (g_cluster.localNode->escalated == false) + { + ereport(LOG, + (errmsg("quorum found"), + errdetail("starting escalation process"))); + start_escalated_node(); + } } + /* inform to the cluster about the new quorum status */ + send_message_of_type(NULL, WD_INFO_MESSAGE, NULL); + register_watchdog_quorum_change_interupt(); } - /* inform to the cluster about the new quorum status */ - send_message_of_type(NULL, WD_INFO_MESSAGE,NULL); - register_watchdog_quorum_change_interupt(); } - } break; case WD_EVENT_NW_IP_IS_REMOVED: - { - /* check if we were holding the virtual IP and it is now lost */ - List* local_addresses = get_all_local_ips(); - if (local_addresses == NULL) - { - /* - * We have lost all IP addresses - * we are in network trouble. Just move to - * in network trouble state - */ - set_state(WD_IN_NW_TROUBLE); - } - else { - /* We do have some IP addresses assigned - * so its not a total black-out - * check if we still have the VIP assigned - */ - if (g_cluster.clusterMasterInfo.holding_vip == true) + /* check if we were holding the virtual IP and it is now lost */ + List *local_addresses = get_all_local_ips(); + + if (local_addresses == NULL) { - ListCell *lc; - bool vip_exists = false; - foreach(lc, local_addresses) + /* + * We have lost all IP addresses we are in network + * trouble. Just move to in network trouble state + */ + set_state(WD_IN_NW_TROUBLE); + } + else + { + /* + * We do have some IP addresses assigned so its not a + * total black-out check if we still have the VIP assigned + */ + if (g_cluster.clusterMasterInfo.holding_vip == true) { - char* ip = lfirst(lc); - if (!strcmp(ip,g_cluster.localNode->delegate_ip)) + ListCell *lc; + bool vip_exists = false; + + foreach(lc, local_addresses) { - vip_exists = true; - break; + char *ip = lfirst(lc); + + if (!strcmp(ip, g_cluster.localNode->delegate_ip)) + { + vip_exists = true; + break; + } } + if (vip_exists == false) + { + /* + * Okay this is the case when only our VIP is lost + * but network interface seems to be working fine + * try to re-aquire the VIP + */ + wd_IP_up(); + } + list_free_deep(local_addresses); + local_addresses = NULL; } - if (vip_exists == false) - { - /* Okay this is the case when only our VIP is lost - * but network interface seems to be working fine - * try to re-aquire the VIP - */ - wd_IP_up(); - } - list_free_deep(local_addresses); - local_addresses = NULL; } } - } break; case WD_EVENT_NW_IP_IS_ASSIGNED: break; case WD_EVENT_TIMEOUT: - { - send_cluster_command(NULL, WD_IAM_COORDINATOR_MESSAGE, 5); - set_timeout(BEACON_MESSAGE_INTERVAL_SECONDS); - } + { + send_cluster_command(NULL, WD_IAM_COORDINATOR_MESSAGE, 5); + set_timeout(BEACON_MESSAGE_INTERVAL_SECONDS); + } break; case WD_EVENT_REMOTE_NODE_LOST: - { - standby_node_left_cluster(wdNode); - } + { + standby_node_left_cluster(wdNode); + } break; case WD_EVENT_PACKET_RCV: - { - switch (pkt->type) { - case WD_STAND_FOR_COORDINATOR_MESSAGE: - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - break; - case WD_DECLARE_COORDINATOR_MESSAGE: - ereport(NOTICE, - (errmsg("We are corrdinator and another node tried a coup"))); - reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); - break; - - case WD_IAM_COORDINATOR_MESSAGE: + switch (pkt->type) { - ereport(NOTICE, - (errmsg("We are in split brain, I AM COORDINATOR MESSAGE received from \"%s\" node",wdNode->nodeName))); + case WD_STAND_FOR_COORDINATOR_MESSAGE: + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + break; + case WD_DECLARE_COORDINATOR_MESSAGE: + ereport(NOTICE, + (errmsg("We are corrdinator and another node tried a coup"))); + reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); + break; - if (beacon_message_received_from_node(wdNode, pkt) == true) - { - handle_split_brain(wdNode, pkt); - } - else - { - /* we are not able to decide which should be the - * best candidate to stay as master/coordinator node - * This could also happen if the remote node is using the - * older version of Pgpool-II which send the empty - * beacon messages. - */ - ereport(LOG, - (errmsg("We are in split brain, and not able to decide the best candidate for master/coordinator"), - errdetail("re-initializing the local watchdog cluster state"))); + case WD_IAM_COORDINATOR_MESSAGE: + { + ereport(NOTICE, + (errmsg("We are in split brain, I AM COORDINATOR MESSAGE received from \"%s\" node", wdNode->nodeName))); - send_cluster_service_message(wdNode,pkt,CLUSTER_NEEDS_ELECTION); - set_state(WD_JOINING); - } - } - break; + if (beacon_message_received_from_node(wdNode, pkt) == true) + { + handle_split_brain(wdNode, pkt); + } + else + { + /* + * we are not able to decide which should be + * the best candidate to stay as + * master/coordinator node This could also + * happen if the remote node is using the + * older version of Pgpool-II which send the + * empty beacon messages. + */ + ereport(LOG, + (errmsg("We are in split brain, and not able to decide the best candidate for master/coordinator"), + errdetail("re-initializing the local watchdog cluster state"))); + + send_cluster_service_message(wdNode, pkt, CLUSTER_NEEDS_ELECTION); + set_state(WD_JOINING); + } + } + break; - case WD_JOIN_COORDINATOR_MESSAGE: - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - /* Also get the configurations from the standby node */ - send_message_of_type(wdNode,WD_ASK_FOR_POOL_CONFIG,NULL); - standby_node_join_cluster(wdNode); - } - break; + case WD_JOIN_COORDINATOR_MESSAGE: + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - default: - standard_packet_processor(wdNode, pkt); - break; + /* + * Also get the configurations from the standby + * node + */ + send_message_of_type(wdNode, WD_ASK_FOR_POOL_CONFIG, NULL); + standby_node_join_cluster(wdNode); + } + break; + + default: + standard_packet_processor(wdNode, pkt); + break; + } } - } break; - + default: break; } @@ -5457,91 +5712,96 @@ static int watchdog_state_machine_coordinator(WD_EVENTS event, WatchdogNode* wdN * and incorrect from the other pgpool-II nodes in the cluster. So the ideal solution * for the situation is to make the pgpool-II main process aware of the network black out * and when the network recovers the pgpool-II asks the watchdog to sync again the state of - * all configured backend nodes from the master pgpool-II node. But to implement this lot + * all configured backend nodes from the master pgpool-II node. But to implement this lot * of time is required, So until that time we are just opting for the easiest solution here * which is to commit a suicide as soon an the network becomes unreachable */ -static int watchdog_state_machine_nw_error(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_nw_error(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { case WD_EVENT_WD_STATE_CHANGED: /* commit suicide, see above note */ ereport(FATAL, - (return_code(POOL_EXIT_FATAL), + (return_code(POOL_EXIT_FATAL), errmsg("system has lost the network"))); set_timeout(2); break; - + case WD_EVENT_PACKET_RCV: - /* Okay this is funny because according to us - * we are in network black out but yet we are - * able to receive the packet. - * Just check may be network is back and we are - * unable to detect it + + /* + * Okay this is funny because according to us we are in network + * black out but yet we are able to receive the packet. Just check + * may be network is back and we are unable to detect it */ /* fall through */ case WD_EVENT_TIMEOUT: case WD_EVENT_NW_IP_IS_ASSIGNED: - { - List* local_addresses = get_all_local_ips(); - if (local_addresses == NULL) - { - /* How come this is possible ?? - * but if somehow this happens keep in the - * state and ignore the packet - */ - } - else { - /* - * Seems like the network is back - * just go on initialize the cluster - */ - /* we might have broken sockets when the network - * gets back. Send the request info message to all - * nodes to confirm socket state - */ - WDPacketData* pkt = get_minimum_message(WD_IAM_IN_NW_TROUBLE_MESSAGE, NULL); - send_message(NULL,pkt); - try_connecting_with_all_unreachable_nodes(); - pfree(pkt); - list_free_deep(local_addresses); - local_addresses = NULL; - set_state(WD_LOADING); + List *local_addresses = get_all_local_ips(); + + if (local_addresses == NULL) + { + /* + * How come this is possible ?? but if somehow this + * happens keep in the state and ignore the packet + */ + } + else + { + /* + * Seems like the network is back just go on initialize + * the cluster + */ + /* + * we might have broken sockets when the network gets + * back. Send the request info message to all nodes to + * confirm socket state + */ + WDPacketData *pkt = get_minimum_message(WD_IAM_IN_NW_TROUBLE_MESSAGE, NULL); + + send_message(NULL, pkt); + try_connecting_with_all_unreachable_nodes(); + pfree(pkt); + list_free_deep(local_addresses); + local_addresses = NULL; + set_state(WD_LOADING); + } } - } break; - + default: break; } return 0; } -static bool beacon_message_received_from_node(WatchdogNode* wdNode, WDPacketData* pkt) +static bool +beacon_message_received_from_node(WatchdogNode * wdNode, WDPacketData * pkt) { - long seconds_since_node_startup; - long seconds_since_current_state; - int quorum_status; - int standby_nodes_count; - bool escalated; - int state; + long seconds_since_node_startup; + long seconds_since_current_state; + int quorum_status; + int standby_nodes_count; + bool escalated; + int state; struct timeval current_time; - gettimeofday(&current_time,NULL); + gettimeofday(&current_time, NULL); if (pkt->data == NULL || pkt->len <= 0) return false; if (parse_beacon_message_json(pkt->data, pkt->len, - &state, - &seconds_since_node_startup, - &seconds_since_current_state, - &quorum_status, - &standby_nodes_count, - &escalated) == false) + &state, + &seconds_since_node_startup, + &seconds_since_current_state, + &quorum_status, + &standby_nodes_count, + &escalated) == false) { return false; } @@ -5566,7 +5826,8 @@ static bool beacon_message_received_from_node(WatchdogNode* wdNode, WDPacketData * 0 : both local and remote nodes are not worthy master or error * 1 : local node should remain as the master/coordinator */ -static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode) +static int +I_am_master_and_cluser_in_split_brain(WatchdogNode * otherMasterNode) { if (get_local_node_state() != WD_COORDINATOR) return 0; @@ -5577,7 +5838,7 @@ static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode) { ereport(LOG, (errmsg("not enough data to decide the master node"), - errdetail("the watchdog node:\"%s\" is using the older version of Pgpool-II",otherMasterNode->nodeName))); + errdetail("the watchdog node:\"%s\" is using the older version of Pgpool-II", otherMasterNode->nodeName))); return 0; } @@ -5588,8 +5849,8 @@ static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode) { /* remote node stays as the master */ ereport(LOG, - (errmsg("remote node:\"%s\" is best suitable to stay as master because it is escalated and I am not", - otherMasterNode->nodeName))); + (errmsg("remote node:\"%s\" is best suitable to stay as master because it is escalated and I am not", + otherMasterNode->nodeName))); return -1; } else @@ -5627,8 +5888,8 @@ static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode) { /* remote node has more alive nodes */ ereport(LOG, - (errmsg("remote node:\"%s\" is best suitable to stay as master because it has more connected standby nodes" - ,otherMasterNode->nodeName))); + (errmsg("remote node:\"%s\" is best suitable to stay as master because it has more connected standby nodes" + ,otherMasterNode->nodeName))); return -1; } else @@ -5640,14 +5901,14 @@ static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode) return 1; } } - else /* decide on which node is the older mater */ + else /* decide on which node is the older mater */ { if (otherMasterNode->current_state_time.tv_sec < g_cluster.localNode->current_state_time.tv_sec) { /* remote node has more alive nodes */ ereport(LOG, - (errmsg("remote node:\"%s\" is best suitable to stay as master because it is the older master" - ,otherMasterNode->nodeName))); + (errmsg("remote node:\"%s\" is best suitable to stay as master because it is the older master" + ,otherMasterNode->nodeName))); return -1; } @@ -5655,30 +5916,32 @@ static int I_am_master_and_cluser_in_split_brain(WatchdogNode* otherMasterNode) { /* local node should keep the master status */ ereport(LOG, - (errmsg("remote node:\"%s\" should step down from master because we are the older master" - ,otherMasterNode->nodeName))); + (errmsg("remote node:\"%s\" should step down from master because we are the older master" + ,otherMasterNode->nodeName))); return 1; } } - return 0; /* keep the compiler quite */ + return 0; /* keep the compiler quite */ } -static void handle_split_brain(WatchdogNode* otherMasterNode, WDPacketData* pkt) +static void +handle_split_brain(WatchdogNode * otherMasterNode, WDPacketData * pkt) { - int decide_master = I_am_master_and_cluser_in_split_brain(otherMasterNode); + int decide_master = I_am_master_and_cluser_in_split_brain(otherMasterNode); + if (decide_master == 0) { - /* we are not able to decide which should be the - * best candidate to stay as master/coordinator node - * This could also happen if the remote node is using the - * older version of Pgpool-II which send the empty - * beacon messages. + /* + * we are not able to decide which should be the best candidate to + * stay as master/coordinator node This could also happen if the + * remote node is using the older version of Pgpool-II which send the + * empty beacon messages. */ ereport(LOG, (errmsg("We are in split brain, and not able to decide the best candidate for master/coordinator"), errdetail("re-initializing the local watchdog cluster state"))); - send_cluster_service_message(otherMasterNode,pkt,CLUSTER_NEEDS_ELECTION); + send_cluster_service_message(otherMasterNode, pkt, CLUSTER_NEEDS_ELECTION); set_state(WD_JOINING); } else if (decide_master == -1) @@ -5689,7 +5952,7 @@ static void handle_split_brain(WatchdogNode* otherMasterNode, WDPacketData* pkt) ,otherMasterNode->nodeName), errdetail("re-initializing the local watchdog cluster state"))); /* brodcast the message about I am not the true master node */ - send_cluster_service_message(NULL,pkt,CLUSTER_IAM_NOT_TRUE_MASTER); + send_cluster_service_message(NULL, pkt, CLUSTER_IAM_NOT_TRUE_MASTER); set_state(WD_JOINING); } else @@ -5697,30 +5960,31 @@ static void handle_split_brain(WatchdogNode* otherMasterNode, WDPacketData* pkt) /* I am the best candidate for the master node */ ereport(LOG, (errmsg("We are in split brain, and I am the best candidate for master/coordinator"), - errdetail("asking the remote node \"%s\" to step down",otherMasterNode->nodeName))); - send_cluster_service_message(otherMasterNode,pkt,CLUSTER_IAM_TRUE_MASTER); + errdetail("asking the remote node \"%s\" to step down", otherMasterNode->nodeName))); + send_cluster_service_message(otherMasterNode, pkt, CLUSTER_IAM_TRUE_MASTER); } } -static void start_escalated_node(void) +static void +start_escalated_node(void) { - int wait_secs = MAX_SECS_ESC_PROC_EXIT_WAIT; + int wait_secs = MAX_SECS_ESC_PROC_EXIT_WAIT; + if (g_cluster.localNode->escalated == true) /* already escalated */ return; while (g_cluster.de_escalation_pid > 0 && wait_secs-- > 0) { /* - * de_escalation proceess was already running and we are - * esclating again. - * give some time to de-escalation process to exit normaly + * de_escalation proceess was already running and we are esclating + * again. give some time to de-escalation process to exit normaly */ ereport(LOG, (errmsg("waiting for de-escalation process to exit before starting escalation"))); if (sigchld_request) wd_child_signal_handler(); - sleep (1); + sleep(1); } if (g_cluster.de_escalation_pid > 0) ereport(LOG, @@ -5733,7 +5997,7 @@ static void start_escalated_node(void) g_cluster.localNode->escalated = true; set_watchdog_node_escalated(); ereport(LOG, - (errmsg("escalation process started with PID:%d",g_cluster.escalation_pid))); + (errmsg("escalation process started with PID:%d", g_cluster.escalation_pid))); if (strlen(g_cluster.localNode->delegate_ip) > 0) g_cluster.clusterMasterInfo.holding_vip = true; } @@ -5744,28 +6008,29 @@ static void start_escalated_node(void) } } -static void resign_from_escalated_node(void) +static void +resign_from_escalated_node(void) { - int wait_secs = MAX_SECS_ESC_PROC_EXIT_WAIT; + int wait_secs = MAX_SECS_ESC_PROC_EXIT_WAIT; + if (g_cluster.localNode->escalated == false) return; while (g_cluster.escalation_pid > 0 && wait_secs-- > 0) { /* - * escalation proceess was already running and we are - * resigning from it. - * wait for the escalation process to exit normaly + * escalation proceess was already running and we are resigning from + * it. wait for the escalation process to exit normaly */ ereport(LOG, (errmsg("waiting for escalation process to exit before starting de-escalation"))); if (sigchld_request) wd_child_signal_handler(); - sleep (1); + sleep(1); } if (g_cluster.escalation_pid > 0) ereport(LOG, - (errmsg("escalation process does not exited in time"), + (errmsg("escalation process does not exited in time"), errdetail("starting the de-escalation anyway"))); g_cluster.de_escalation_pid = fork_plunging_process(); g_cluster.clusterMasterInfo.holding_vip = false; @@ -5776,72 +6041,74 @@ static void resign_from_escalated_node(void) /* * state machine function for state participate in elections */ -static int watchdog_state_machine_voting(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_voting(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { case WD_EVENT_WD_STATE_CHANGED: set_timeout(MAX_SECS_WAIT_FOR_REPLY_FROM_NODE); break; - + case WD_EVENT_TIMEOUT: set_state(WD_JOINING); break; case WD_EVENT_PACKET_RCV: - { - if(pkt == NULL) - { - ereport(LOG, - (errmsg("packet is NULL"))); - break; - } - switch (pkt->type) { - case WD_STAND_FOR_COORDINATOR_MESSAGE: + if (pkt == NULL) { - /* Check the node priority */ - if (wdNode->wd_priority >= g_cluster.localNode->wd_priority) - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - } - else - { - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - set_state(WD_STAND_FOR_COORDINATOR); - } - } - break; - case WD_IAM_COORDINATOR_MESSAGE: - set_state(WD_JOINING); - break; - case WD_DECLARE_COORDINATOR_MESSAGE: - /* Check the node priority */ - if (wdNode->wd_priority >= g_cluster.localNode->wd_priority) - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - set_state(WD_INITIALIZING); - } - else - { - reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); - set_state(WD_STAND_FOR_COORDINATOR); - } - break; - default: - standard_packet_processor(wdNode, pkt); + ereport(LOG, + (errmsg("packet is NULL"))); break; + } + switch (pkt->type) + { + case WD_STAND_FOR_COORDINATOR_MESSAGE: + { + /* Check the node priority */ + if (wdNode->wd_priority >= g_cluster.localNode->wd_priority) + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + } + else + { + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + set_state(WD_STAND_FOR_COORDINATOR); + } + } + break; + case WD_IAM_COORDINATOR_MESSAGE: + set_state(WD_JOINING); + break; + case WD_DECLARE_COORDINATOR_MESSAGE: + /* Check the node priority */ + if (wdNode->wd_priority >= g_cluster.localNode->wd_priority) + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + set_state(WD_INITIALIZING); + } + else + { + reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); + set_state(WD_STAND_FOR_COORDINATOR); + } + break; + default: + standard_packet_processor(wdNode, pkt); + break; + } } - } break; - + default: break; } return 0; } -static int watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* clusterCommand) +static int +watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * clusterCommand) { switch (event) { @@ -5854,130 +6121,133 @@ static int watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode* wdNode, break; case WD_EVENT_COMMAND_FINISHED: - { - if (clusterCommand->commandPacket.type == WD_JOIN_COORDINATOR_MESSAGE) { - if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED || - clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + if (clusterCommand->commandPacket.type == WD_JOIN_COORDINATOR_MESSAGE) { - register_watchdog_state_change_interupt(); + if (clusterCommand->commandStatus == COMMAND_FINISHED_ALL_REPLIED || + clusterCommand->commandStatus == COMMAND_FINISHED_TIMEOUT) + { + register_watchdog_state_change_interupt(); - ereport(LOG, - (errmsg("successfully joined the watchdog cluster as standby node"), - errdetail("our join coordinator request is accepted by cluster leader node \"%s\"",WD_MASTER_NODE->nodeName))); - } - else - { - ereport(NOTICE, - (errmsg("our join coordinator is rejected by node \"%s\"",wdNode->nodeName), - errhint("rejoining the cluster."))); - set_state(WD_JOINING); + ereport(LOG, + (errmsg("successfully joined the watchdog cluster as standby node"), + errdetail("our join coordinator request is accepted by cluster leader node \"%s\"", WD_MASTER_NODE->nodeName))); + } + else + { + ereport(NOTICE, + (errmsg("our join coordinator is rejected by node \"%s\"", wdNode->nodeName), + errhint("rejoining the cluster."))); + set_state(WD_JOINING); + } } } - } break; case WD_EVENT_REMOTE_NODE_LOST: - { - /* - * we have lost one remote connected node - * check if the node was coordinator - */ - if (WD_MASTER_NODE == NULL) { - ereport(LOG, - (errmsg("We have lost the cluster master node \"%s\"",wdNode->nodeName))); - set_state(WD_JOINING); + /* + * we have lost one remote connected node check if the node + * was coordinator + */ + if (WD_MASTER_NODE == NULL) + { + ereport(LOG, + (errmsg("We have lost the cluster master node \"%s\"", wdNode->nodeName))); + set_state(WD_JOINING); + } } - } break; case WD_EVENT_PACKET_RCV: - { - switch (pkt->type) { - case WD_FAILOVER_END: + switch (pkt->type) { - register_backend_state_sync_req_interupt(); - } - break; + case WD_FAILOVER_END: + { + register_backend_state_sync_req_interupt(); + } + break; - case WD_STAND_FOR_COORDINATOR_MESSAGE: - { - if (WD_MASTER_NODE == NULL) - { - reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); - set_state(WD_PARTICIPATE_IN_ELECTION); - } - else - { - reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); - set_state(WD_JOINING); - } - } - break; + case WD_STAND_FOR_COORDINATOR_MESSAGE: + { + if (WD_MASTER_NODE == NULL) + { + reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); + set_state(WD_PARTICIPATE_IN_ELECTION); + } + else + { + reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); + set_state(WD_JOINING); + } + } + break; - case WD_DECLARE_COORDINATOR_MESSAGE: - { - if (wdNode != WD_MASTER_NODE) - { - /* - * we already have a master node - * and we got a new node trying to be master - * re-initialize the cluster, something is wrong - */ - reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); - } - else - { - set_state(WD_JOINING); - } - } - break; + case WD_DECLARE_COORDINATOR_MESSAGE: + { + if (wdNode != WD_MASTER_NODE) + { + /* + * we already have a master node and we got a + * new node trying to be master re-initialize + * the cluster, something is wrong + */ + reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); + } + else + { + set_state(WD_JOINING); + } + } + break; - case WD_IAM_COORDINATOR_MESSAGE: - { - /* - * if the message is received from coordinator reply with info, - * otherwise reject - */ - if (wdNode != WD_MASTER_NODE) - { - ereport(LOG, - (errmsg("\"%s\" is our coordinator node, but \"%s\" is also announcing as a coordinator", - WD_MASTER_NODE->nodeName,wdNode->nodeName), - errdetail("broadcasting the cluster in split-brain message"))); + case WD_IAM_COORDINATOR_MESSAGE: + { + /* + * if the message is received from coordinator + * reply with info, otherwise reject + */ + if (wdNode != WD_MASTER_NODE) + { + ereport(LOG, + (errmsg("\"%s\" is our coordinator node, but \"%s\" is also announcing as a coordinator", + WD_MASTER_NODE->nodeName, wdNode->nodeName), + errdetail("broadcasting the cluster in split-brain message"))); - send_cluster_service_message(NULL,pkt,CLUSTER_IN_SPLIT_BRAIN); - } - else - { - send_message_of_type(wdNode, WD_INFO_MESSAGE, pkt); - beacon_message_received_from_node(wdNode, pkt); - } - } - break; + send_cluster_service_message(NULL, pkt, CLUSTER_IN_SPLIT_BRAIN); + } + else + { + send_message_of_type(wdNode, WD_INFO_MESSAGE, pkt); + beacon_message_received_from_node(wdNode, pkt); + } + } + break; - default: - standard_packet_processor(wdNode, pkt); - break; + default: + standard_packet_processor(wdNode, pkt); + break; + } } - } - break; + break; default: break; } - /* before returning from the function make sure that - * we are connected with the master node + /* + * before returning from the function make sure that we are connected with + * the master node */ if (WD_MASTER_NODE) { struct timeval currTime; + gettimeofday(&currTime, NULL); - int last_rcv_sec = WD_TIME_DIFF_SEC(currTime,WD_MASTER_NODE->last_rcv_time); - if (last_rcv_sec >= (2 * BEACON_MESSAGE_INTERVAL_SECONDS)) + int last_rcv_sec = WD_TIME_DIFF_SEC(currTime, WD_MASTER_NODE->last_rcv_time); + + if (last_rcv_sec >= (2 * BEACON_MESSAGE_INTERVAL_SECONDS)) { /* we have missed atleast two beacons from master node */ ereport(WARNING, @@ -5987,16 +6257,17 @@ static int watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode* wdNode, set_state(WD_JOINING); } - else if (last_rcv_sec >= BEACON_MESSAGE_INTERVAL_SECONDS) + else if (last_rcv_sec >= BEACON_MESSAGE_INTERVAL_SECONDS) { - /* We have not received a last becacon from master - * ask for the node info from master node + /* + * We have not received a last becacon from master ask for the + * node info from master node */ ereport(WARNING, (errmsg("we have not received a beacon message from master node \"%s\"", WD_MASTER_NODE->nodeName), errdetail("requesting info message from master node"))); - send_message_of_type(WD_MASTER_NODE,WD_REQ_INFO_MESSAGE,NULL); + send_message_of_type(WD_MASTER_NODE, WD_REQ_INFO_MESSAGE, NULL); } } return 0; @@ -6014,18 +6285,19 @@ static int watchdog_state_machine_standby(WD_EVENTS event, WatchdogNode* wdNode, * 1: * quorum exists */ -static void update_quorum_status(void) +static void +update_quorum_status(void) { - int quorum_status = g_cluster.quorum_status; + int quorum_status = g_cluster.quorum_status; - if ( g_cluster.clusterMasterInfo.standby_nodes_count > get_mimimum_nodes_required_for_quorum()) + if (g_cluster.clusterMasterInfo.standby_nodes_count > get_mimimum_nodes_required_for_quorum()) { g_cluster.quorum_status = 1; } - else if ( g_cluster.clusterMasterInfo.standby_nodes_count == get_mimimum_nodes_required_for_quorum()) + else if (g_cluster.clusterMasterInfo.standby_nodes_count == get_mimimum_nodes_required_for_quorum()) { if (g_cluster.remoteNodeCount % 2 != 0) - g_cluster.quorum_status = 0; /* on the edge */ + g_cluster.quorum_status = 0; /* on the edge */ else g_cluster.quorum_status = 1; } @@ -6041,20 +6313,21 @@ static void update_quorum_status(void) } /* returns the minimum number of remote nodes required for quorum */ -static int get_mimimum_nodes_required_for_quorum(void) +static int +get_mimimum_nodes_required_for_quorum(void) { /* - * Even numner of remote nodes, That means total number of nodes - * are odd, so minimum quorum is just remote/2 + * Even numner of remote nodes, That means total number of nodes are odd, + * so minimum quorum is just remote/2 */ if (g_cluster.remoteNodeCount % 2 == 0) return (g_cluster.remoteNodeCount / 2); /* - * Total nodes including self are even, So we consider 50% - * nodes as quorum, should we? + * Total nodes including self are even, So we consider 50% nodes as + * quorum, should we? */ - return ((g_cluster.remoteNodeCount - 1 ) / 2); + return ((g_cluster.remoteNodeCount - 1) / 2); } @@ -6062,14 +6335,20 @@ static int get_mimimum_nodes_required_for_quorum(void) * sets the state of local watchdog node, and fires a state change event * if the new and old state differes */ -static int set_state(WD_STATES newState) +static int +set_state(WD_STATES newState) { - WD_STATES oldState = get_local_node_state(); + WD_STATES oldState = get_local_node_state(); + g_cluster.localNode->state = newState; if (oldState != newState) { gettimeofday(&g_cluster.localNode->current_state_time, NULL); - /* if we changing from the coordinator state, do the de-escalation if required */ + + /* + * if we changing from the coordinator state, do the de-escalation if + * required + */ if (oldState == WD_COORDINATOR) { resign_from_escalated_node(); @@ -6078,26 +6357,27 @@ static int set_state(WD_STATES newState) } ereport(LOG, - (errmsg("watchdog node state changed from [%s] to [%s]",wd_state_names[oldState],wd_state_names[newState]))); + (errmsg("watchdog node state changed from [%s] to [%s]", wd_state_names[oldState], wd_state_names[newState]))); watchdog_state_machine(WD_EVENT_WD_STATE_CHANGED, NULL, NULL, NULL); /* send out the info message to all nodes */ - send_message_of_type(NULL, WD_INFO_MESSAGE,NULL); + send_message_of_type(NULL, WD_INFO_MESSAGE, NULL); } return 0; } -static void allocate_resultNodes_in_command(WDCommandData* ipcCommand) +static void +allocate_resultNodes_in_command(WDCommandData * ipcCommand) { MemoryContext oldCxt; - int i; - + int i; + if (ipcCommand->nodeResults != NULL) return; - + oldCxt = MemoryContextSwitchTo(ipcCommand->memoryContext); ipcCommand->nodeResults = palloc0((sizeof(WDCommandNodeResult) * g_cluster.remoteNodeCount)); - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { ipcCommand->nodeResults[i].wdNode = &g_cluster.remoteNodes[i]; } @@ -6105,11 +6385,12 @@ static void allocate_resultNodes_in_command(WDCommandData* ipcCommand) } -static void process_remote_online_recovery_command(WatchdogNode* wdNode, WDPacketData* pkt) +static void +process_remote_online_recovery_command(WatchdogNode * wdNode, WDPacketData * pkt) { - char* func_name; - int node_count = 0; - int *node_id_list = NULL; + char *func_name; + int node_count = 0; + int *node_id_list = NULL; unsigned char flags; if (pkt->data == NULL || pkt->len == 0) @@ -6122,7 +6403,7 @@ static void process_remote_online_recovery_command(WatchdogNode* wdNode, WDPacke } ereport(LOG, - (errmsg("watchdog received online recovery request from \"%s\"",wdNode->nodeName))); + (errmsg("watchdog received online recovery request from \"%s\"", wdNode->nodeName))); if (parse_wd_node_function_json(pkt->data, pkt->len, &func_name, &node_id_list, &node_count, &flags)) { @@ -6139,19 +6420,19 @@ static void process_remote_online_recovery_command(WatchdogNode* wdNode, WDPacke { reply_with_minimal_message(wdNode, WD_ACCEPT_MESSAGE, pkt); } - else if(pool_config->recovery_timeout <= 0) + else if (pool_config->recovery_timeout <= 0) { reply_with_minimal_message(wdNode, WD_REJECT_MESSAGE, pkt); } else { - WDFunctionCommandData* wd_func_command; + WDFunctionCommandData *wd_func_command; MemoryContext oldCxt = MemoryContextSwitchTo(TopMemoryContext); wd_func_command = palloc(sizeof(WDFunctionCommandData)); wd_func_command->commandType = pkt->type; wd_func_command->commandID = pkt->command_id; - wd_func_command->funcName = MemoryContextStrdup(TopMemoryContext,func_name); + wd_func_command->funcName = MemoryContextStrdup(TopMemoryContext, func_name); wd_func_command->wdNode = wdNode; /* Add this command for timer tick */ @@ -6170,19 +6451,19 @@ static void process_remote_online_recovery_command(WatchdogNode* wdNode, WDPacke else { ereport(LOG, - (errmsg("watchdog failed to process online recovery request"), - errdetail("invalid command [%s] in online recovery request from \"%s\"",func_name,wdNode->nodeName))); + (errmsg("watchdog failed to process online recovery request"), + errdetail("invalid command [%s] in online recovery request from \"%s\"", func_name, wdNode->nodeName))); reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); } } else { ereport(LOG, - (errmsg("watchdog failed to process online recovery request"), - errdetail("invalid data in online recovery request from \"%s\"",wdNode->nodeName))); + (errmsg("watchdog failed to process online recovery request"), + errdetail("invalid data in online recovery request from \"%s\"", wdNode->nodeName))); reply_with_minimal_message(wdNode, WD_ERROR_MESSAGE, pkt); } - + if (func_name) pfree(func_name); if (node_id_list) @@ -6190,15 +6471,17 @@ static void process_remote_online_recovery_command(WatchdogNode* wdNode, WDPacke } -static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode* wdNode, WDPacketData* pkt, WDCommandData* ipcCommand) +static bool +reply_is_received_for_pgpool_replicate_command(WatchdogNode * wdNode, WDPacketData * pkt, WDCommandData * ipcCommand) { - int i; - WDCommandNodeResult* nodeResult = NULL; + int i; + WDCommandNodeResult *nodeResult = NULL; + /* get the result node for */ ereport(DEBUG1, - (errmsg("watchdog node \"%s\" has replied for pgpool-II replicate command packet",wdNode->nodeName))); + (errmsg("watchdog node \"%s\" has replied for pgpool-II replicate command packet", wdNode->nodeName))); - for (i=0; i< g_cluster.remoteNodeCount; i++) + for (i = 0; i < g_cluster.remoteNodeCount; i++) { nodeResult = &ipcCommand->nodeResults[i]; if (nodeResult->wdNode == wdNode) @@ -6208,7 +6491,7 @@ static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode* wdNode, if (nodeResult == NULL) { ereport(WARNING, - (errmsg("unable to find result node for pgpool-II replicate command packet received from watchdog node \"%s\"",wdNode->nodeName))); + (errmsg("unable to find result node for pgpool-II replicate command packet received from watchdog node \"%s\"", wdNode->nodeName))); return true; } @@ -6216,8 +6499,8 @@ static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode* wdNode, nodeResult->cmdState = COMMAND_STATE_REPLIED; ipcCommand->commandReplyFromCount++; ereport(DEBUG2, - (errmsg("watchdog node \"%s\" has replied for pgpool-II replicate command packet",wdNode->nodeName), - errdetail("command was sent to %d nodes and %d nodes have replied to it",ipcCommand->commandSendToCount,ipcCommand->commandReplyFromCount))); + (errmsg("watchdog node \"%s\" has replied for pgpool-II replicate command packet", wdNode->nodeName), + errdetail("command was sent to %d nodes and %d nodes have replied to it", ipcCommand->commandSendToCount, ipcCommand->commandReplyFromCount))); if (pkt->type != WD_ACCEPT_MESSAGE) { @@ -6229,8 +6512,7 @@ static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode* wdNode, else if (ipcCommand->commandReplyFromCount >= ipcCommand->commandSendToCount) { /* - * we have received results from all nodes - * analyze the result + * we have received results from all nodes analyze the result */ ipcCommand->commandStatus = COMMAND_FINISHED_ALL_REPLIED; wd_command_is_complete(ipcCommand); @@ -6244,7 +6526,8 @@ static bool reply_is_received_for_pgpool_replicate_command(WatchdogNode* wdNode, /* * return true if want to cancel timer, */ -static bool process_wd_command_timer_event(bool timer_expired, WDFunctionCommandData* wd_func_command) +static bool +process_wd_command_timer_event(bool timer_expired, WDFunctionCommandData * wd_func_command) { if (wd_func_command->commandType == WD_IPC_ONLINE_RECOVERY_COMMAND) { @@ -6253,6 +6536,7 @@ static bool process_wd_command_timer_event(bool timer_expired, WDFunctionCommand if (Req_info->conn_counter == 0) { WDPacketData emptyPkt; + emptyPkt.command_id = wd_func_command->commandID; reply_with_minimal_message(wd_func_command->wdNode, WD_ACCEPT_MESSAGE, &emptyPkt); return true; @@ -6260,6 +6544,7 @@ static bool process_wd_command_timer_event(bool timer_expired, WDFunctionCommand else if (timer_expired) { WDPacketData emptyPkt; + emptyPkt.command_id = wd_func_command->commandID; reply_with_minimal_message(wd_func_command->wdNode, WD_REJECT_MESSAGE, &emptyPkt); return true; @@ -6267,60 +6552,65 @@ static bool process_wd_command_timer_event(bool timer_expired, WDFunctionCommand return false; } } - /* Just remove the timer.*/ + /* Just remove the timer. */ return true; } -static void process_wd_func_commands_for_timer_events(void) +static void +process_wd_func_commands_for_timer_events(void) { struct timeval currTime; - ListCell *lc; - List* timers_to_del = NIL; - + ListCell *lc; + List *timers_to_del = NIL; + if (g_cluster.wd_timer_commands == NULL) - return; + return; gettimeofday(&currTime, NULL); foreach(lc, g_cluster.wd_timer_commands) { - WDCommandTimerData* timerData = lfirst(lc); + WDCommandTimerData *timerData = lfirst(lc); + if (timerData) { - bool del = false; - if (WD_TIME_DIFF_SEC(currTime,timerData->startTime) >= timerData->expire_sec) + bool del = false; + + if (WD_TIME_DIFF_SEC(currTime, timerData->startTime) >= timerData->expire_sec) { del = process_wd_command_timer_event(true, timerData->wd_func_command); - + } else if (timerData->need_tics) { del = process_wd_command_timer_event(false, timerData->wd_func_command); } if (del) - timers_to_del = lappend(timers_to_del,timerData); + timers_to_del = lappend(timers_to_del, timerData); } } foreach(lc, timers_to_del) { - g_cluster.wd_timer_commands = list_delete_ptr(g_cluster.wd_timer_commands,lfirst(lc)); + g_cluster.wd_timer_commands = list_delete_ptr(g_cluster.wd_timer_commands, lfirst(lc)); } } -static void add_wd_command_for_timer_events(unsigned int expire_secs, bool need_tics, WDFunctionCommandData* wd_func_command) +static void +add_wd_command_for_timer_events(unsigned int expire_secs, bool need_tics, WDFunctionCommandData * wd_func_command) { /* create a new Timer struct */ MemoryContext oldCtx = MemoryContextSwitchTo(TopMemoryContext); - WDCommandTimerData* timerData = palloc(sizeof(WDCommandTimerData)); - gettimeofday(&timerData->startTime,NULL); + WDCommandTimerData *timerData = palloc(sizeof(WDCommandTimerData)); + + gettimeofday(&timerData->startTime, NULL); timerData->expire_sec = expire_secs; timerData->need_tics = need_tics; timerData->wd_func_command = wd_func_command; - - g_cluster.wd_timer_commands = lappend(g_cluster.wd_timer_commands,timerData); - + + g_cluster.wd_timer_commands = lappend(g_cluster.wd_timer_commands, timerData); + MemoryContextSwitchTo(oldCtx); - + } #define WD_VERIFY_RECEIVED_CONFIG_PARAMETER_VAL_INT(config_obj, wdNode, parameter) \ @@ -6350,9 +6640,11 @@ do { \ } \ } while(0) -static void verify_pool_configurations(WatchdogNode* wdNode, POOL_CONFIG* config) +static void +verify_pool_configurations(WatchdogNode * wdNode, POOL_CONFIG * config) { - int i; + int i; + WD_VERIFY_RECEIVED_CONFIG_PARAMETER_VAL_INT(config, wdNode, num_init_children); WD_VERIFY_RECEIVED_CONFIG_PARAMETER_VAL_INT(config, wdNode, listen_backlog_multiplier); WD_VERIFY_RECEIVED_CONFIG_PARAMETER_VAL_INT(config, wdNode, child_life_time); @@ -6395,12 +6687,12 @@ static void verify_pool_configurations(WatchdogNode* wdNode, POOL_CONFIG* config wdNode->nodeName, config->backend_desc->num_backends))); } - for (i=0; i < pool_config->backend_desc->num_backends; i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { if (strncasecmp(pool_config->backend_desc->backend_info[i].backend_hostname, config->backend_desc->backend_info[i].backend_hostname, sizeof(pool_config->backend_desc->backend_info[i].backend_hostname))) { ereport(WARNING, - (errmsg("configurations value for backend[%d] \"hostname\" on node \"%s\" is different",i, wdNode->nodeName), + (errmsg("configurations value for backend[%d] \"hostname\" on node \"%s\" is different", i, wdNode->nodeName), errdetail("\"backend_hostname%d\" on this node is %s while on \"%s\" is %s", i, pool_config->backend_desc->backend_info[i].backend_hostname, @@ -6410,7 +6702,7 @@ static void verify_pool_configurations(WatchdogNode* wdNode, POOL_CONFIG* config if (config->backend_desc->backend_info[i].backend_port != pool_config->backend_desc->backend_info[i].backend_port) { ereport(WARNING, - (errmsg("configurations value for backend[%d] \"port\" on node \"%s\" is different",i, wdNode->nodeName), + (errmsg("configurations value for backend[%d] \"port\" on node \"%s\" is different", i, wdNode->nodeName), errdetail("\"backend_port%d\" on this node is %d while on \"%s\" is %d", i, pool_config->backend_desc->backend_info[i].backend_port, @@ -6430,44 +6722,46 @@ static void verify_pool_configurations(WatchdogNode* wdNode, POOL_CONFIG* config } } -static bool get_authhash_for_node(WatchdogNode* wdNode, char* authhash) +static bool +get_authhash_for_node(WatchdogNode * wdNode, char *authhash) { if (strlen(pool_config->wd_authkey)) { - char nodeStr[WD_MAX_PACKET_STRING + 1]; - int len = snprintf(nodeStr, WD_MAX_PACKET_STRING, "state=%d wd_port=%d", - wdNode->state, wdNode->wd_port); - - + char nodeStr[WD_MAX_PACKET_STRING + 1]; + int len = snprintf(nodeStr, WD_MAX_PACKET_STRING, "state=%d wd_port=%d", + wdNode->state, wdNode->wd_port); + + /* calculate hash from packet */ wd_calc_hash(nodeStr, len, authhash); if (authhash[0] == '\0') ereport(WARNING, - (errmsg("failed to calculate wd_authkey hash from a send packet"))); + (errmsg("failed to calculate wd_authkey hash from a send packet"))); return true; } return false; } -static bool verify_authhash_for_node(WatchdogNode* wdNode, char* authhash) +static bool +verify_authhash_for_node(WatchdogNode * wdNode, char *authhash) { if (strlen(pool_config->wd_authkey)) { - char calculated_authhash[WD_AUTH_HASH_LEN + 1]; + char calculated_authhash[WD_AUTH_HASH_LEN + 1]; + + char nodeStr[WD_MAX_PACKET_STRING]; + int len = snprintf(nodeStr, WD_MAX_PACKET_STRING, "state=%d wd_port=%d", + wdNode->state, wdNode->wd_port); + - char nodeStr[WD_MAX_PACKET_STRING]; - int len = snprintf(nodeStr, WD_MAX_PACKET_STRING, "state=%d wd_port=%d", - wdNode->state, wdNode->wd_port); - - /* calculate hash from packet */ wd_calc_hash(nodeStr, len, calculated_authhash); if (calculated_authhash[0] == '\0') ereport(WARNING, - (errmsg("failed to calculate wd_authkey hash from a receive packet"))); - return (strcmp(calculated_authhash,authhash) == 0); + (errmsg("failed to calculate wd_authkey hash from a receive packet"))); + return (strcmp(calculated_authhash, authhash) == 0); } - /* authkey is not enabled.*/ + /* authkey is not enabled. */ return true; } @@ -6480,17 +6774,18 @@ static bool verify_authhash_for_node(WatchdogNode* wdNode, char* authhash) * shared key present in the pgpool-II shared memory. This can be used * to restrict certain watchdog IPC functions for outside of pgpool-II */ -static bool check_IPC_client_authentication(json_value *rootObj, bool internal_client_only) +static bool +check_IPC_client_authentication(json_value * rootObj, bool internal_client_only) { - char *packet_auth_key; + char *packet_auth_key; unsigned int packet_key; - bool has_shared_key; + bool has_shared_key; unsigned int *shared_key = get_ipc_shared_key(); - if (json_get_int_value_for_key(rootObj, WD_IPC_SHARED_KEY, (int*)&packet_key)) + if (json_get_int_value_for_key(rootObj, WD_IPC_SHARED_KEY, (int *) &packet_key)) { ereport(DEBUG2, - (errmsg("IPC json data packet does not contain shared key"))); + (errmsg("IPC json data packet does not contain shared key"))); has_shared_key = false; } else @@ -6511,7 +6806,7 @@ static bool check_IPC_client_authentication(json_value *rootObj, bool internal_c if (has_shared_key == false) { ereport(LOG, - (errmsg("invalid json data packet"), + (errmsg("invalid json data packet"), errdetail("authentication shared key not found in json data"))); return false; } @@ -6537,7 +6832,7 @@ static bool check_IPC_client_authentication(json_value *rootObj, bool internal_c if (packet_auth_key == NULL) { ereport(DEBUG1, - (errmsg("invalid json data packet"), + (errmsg("invalid json data packet"), errdetail("authentication key not found in json data"))); return false; } @@ -6553,17 +6848,18 @@ static bool check_IPC_client_authentication(json_value *rootObj, bool internal_c * this one also informs the calling client about the failure */ -static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand) +static bool +check_and_report_IPC_authentication(WDCommandData * ipcCommand) { json_value *root = NULL; - bool internal_client_only = false; - bool ret; + bool internal_client_only = false; + bool ret; if (ipcCommand == NULL) - return false; /* should never happen*/ + return false; /* should never happen */ /* first identify the command type */ - switch(ipcCommand->sourcePacket.type) + switch (ipcCommand->sourcePacket.type) { case WD_NODE_STATUS_CHANGE_COMMAND: case WD_REGISTER_FOR_NOTIFICATION: @@ -6575,7 +6871,7 @@ static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand) case WD_IPC_FAILOVER_COMMAND: case WD_IPC_ONLINE_RECOVERY_COMMAND: case WD_GET_MASTER_DATA_REQUEST: - /* only allowed internaly.*/ + /* only allowed internaly. */ internal_client_only = true; break; @@ -6594,7 +6890,7 @@ static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand) if (ipcCommand->sourcePacket.len <= 0 || ipcCommand->sourcePacket.data == NULL) { ereport(LOG, - (errmsg("authentication failed"), + (errmsg("authentication failed"), errdetail("IPC command contains no data"))); ipcCommand->errorMessage = MemoryContextStrdup(ipcCommand->memoryContext, "authentication failed: invalid data"); @@ -6602,13 +6898,13 @@ static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand) return false; } - root = json_parse(ipcCommand->sourcePacket.data,ipcCommand->sourcePacket.len); + root = json_parse(ipcCommand->sourcePacket.data, ipcCommand->sourcePacket.len); /* The root node must be object */ if (root == NULL || root->type != json_object) { json_value_free(root); ereport(LOG, - (errmsg("authentication failed"), + (errmsg("authentication failed"), errdetail("IPC command contains an invalid data"))); ipcCommand->errorMessage = MemoryContextStrdup(ipcCommand->memoryContext, @@ -6623,7 +6919,7 @@ static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand) if (ret == false) { ereport(WARNING, - (errmsg("authentication failed"), + (errmsg("authentication failed"), errdetail("invalid IPC key"))); ipcCommand->errorMessage = MemoryContextStrdup(ipcCommand->memoryContext, "authentication failed: invalid KEY"); @@ -6631,10 +6927,11 @@ static bool check_and_report_IPC_authentication(WDCommandData* ipcCommand) return ret; } -static void print_watchdog_node_info(WatchdogNode* wdNode) +static void +print_watchdog_node_info(WatchdogNode * wdNode) { ereport(DEBUG2, - (errmsg("state: \"%s\" Host: \"%s\" Name: \"%s\" WD Port:%d PP Port: %d priority:%d", + (errmsg("state: \"%s\" Host: \"%s\" Name: \"%s\" WD Port:%d PP Port: %d priority:%d", wd_state_names[wdNode->state], wdNode->hostname ,wdNode->nodeName @@ -6643,17 +6940,19 @@ static void print_watchdog_node_info(WatchdogNode* wdNode) ,wdNode->wd_priority))); } -static void print_packet_node_info(WDPacketData* pkt,WatchdogNode* wdNode, bool sending) +static void +print_packet_node_info(WDPacketData * pkt, WatchdogNode * wdNode, bool sending) { - int i; + int i; packet_types *pkt_type = NULL; + /* * save the cpu cycles if our log level would swallow this message */ if (pool_config->log_min_messages > DEBUG1) return; - for (i =0; ; i++) + for (i = 0;; i++) { if (all_packet_types[i].type == WD_NO_MESSAGE) break; @@ -6666,29 +6965,31 @@ static void print_packet_node_info(WDPacketData* pkt,WatchdogNode* wdNode, bool } ereport(DEBUG1, - (errmsg("%s packet, watchdog node:[%s] command id:[%d] type:[%s] state:[%s]", - sending?"sending":"received", - wdNode->nodeName, - pkt->command_id, - pkt_type?pkt_type->name:"UNKNOWN", - wd_state_names[get_local_node_state()]))); + (errmsg("%s packet, watchdog node:[%s] command id:[%d] type:[%s] state:[%s]", + sending ? "sending" : "received", + wdNode->nodeName, + pkt->command_id, + pkt_type ? pkt_type->name : "UNKNOWN", + wd_state_names[get_local_node_state()]))); } -static void print_packet_info(WDPacketData* pkt, bool sending) +static void +print_packet_info(WDPacketData * pkt, bool sending) { - int i; + int i; packet_types *pkt_type = NULL; + /* * save the cpu cycles if our log level would swallow this message */ if (pool_config->log_min_messages > DEBUG2) return; - for (i =0; ; i++) + for (i = 0;; i++) { if (all_packet_types[i].type == WD_NO_MESSAGE) break; - + if (all_packet_types[i].type == pkt->type) { pkt_type = &all_packet_types[i]; @@ -6698,15 +6999,17 @@ static void print_packet_info(WDPacketData* pkt, bool sending) ereport(DEBUG2, (errmsg("%s watchdog packet, command id:[%d] type:[%s] state :[%s]", - sending?"sending":"received", + sending ? "sending" : "received", pkt->command_id, - pkt_type?pkt_type->name:"UNKNOWN", + pkt_type ? pkt_type->name : "UNKNOWN", wd_state_names[get_local_node_state()]))); } -static int send_command_packet_to_remote_nodes(WDCommandData* ipcCommand, bool source_included) +static int +send_command_packet_to_remote_nodes(WDCommandData * ipcCommand, bool source_included) { - int i; + int i; + ipcCommand->commandSendToCount = 0; ipcCommand->commandReplyFromCount = 0; ipcCommand->commandSendToErrorCount = 0; @@ -6714,13 +7017,17 @@ static int send_command_packet_to_remote_nodes(WDCommandData* ipcCommand, bool s ereport(DEBUG2, (errmsg("sending the %c type message to \"%s\"", ipcCommand->commandPacket.type, - ipcCommand->sendToNode?ipcCommand->sendToNode->nodeName:"ALL NODES"))); - for (i=0; i< g_cluster.remoteNodeCount; i++) + ipcCommand->sendToNode ? ipcCommand->sendToNode->nodeName : "ALL NODES"))); + for (i = 0; i < g_cluster.remoteNodeCount; i++) { - WDCommandNodeResult* nodeResult = &ipcCommand->nodeResults[i]; + WDCommandNodeResult *nodeResult = &ipcCommand->nodeResults[i]; + if (ipcCommand->sendToNode != NULL && ipcCommand->sendToNode != nodeResult->wdNode) { - /* The command is intended for specific node and this is not the one */ + /* + * The command is intended for specific node and this is not the + * one + */ nodeResult->cmdState = COMMAND_STATE_DO_NOT_SEND; } else if (source_included == false && ipcCommand->sourceWdNode == nodeResult->wdNode && @@ -6728,10 +7035,11 @@ static int send_command_packet_to_remote_nodes(WDCommandData* ipcCommand, bool s { ereport(DEBUG1, (errmsg("not sending the %c type message to command originator node \"%s\"", - ipcCommand->commandPacket.type,nodeResult->wdNode->nodeName))); + ipcCommand->commandPacket.type, nodeResult->wdNode->nodeName))); + /* - * The message is not supposed to be sent to the watchdog - * node that started this command + * The message is not supposed to be sent to the watchdog node + * that started this command */ nodeResult->cmdState = COMMAND_STATE_DO_NOT_SEND; } @@ -6748,7 +7056,7 @@ static int send_command_packet_to_remote_nodes(WDCommandData* ipcCommand, bool s { ereport(DEBUG2, (errmsg("%c type message written to socket for node \"%s\"", - ipcCommand->commandPacket.type,nodeResult->wdNode->nodeName))); + ipcCommand->commandPacket.type, nodeResult->wdNode->nodeName))); nodeResult->cmdState = COMMAND_STATE_SENT; ipcCommand->commandSendToCount++; @@ -6762,38 +7070,42 @@ static int send_command_packet_to_remote_nodes(WDCommandData* ipcCommand, bool s return ipcCommand->commandSendToCount; } -static void set_cluster_master_node(WatchdogNode* wdNode) +static void +set_cluster_master_node(WatchdogNode * wdNode) { if (WD_MASTER_NODE != wdNode) { if (wdNode == NULL) ereport(LOG, (errmsg("unassigning the %s node \"%s\" from watchdog cluster master", - (g_cluster.localNode == WD_MASTER_NODE)? "local":"remote", + (g_cluster.localNode == WD_MASTER_NODE) ? "local" : "remote", WD_MASTER_NODE->nodeName))); else ereport(LOG, (errmsg("setting the %s node \"%s\" as watchdog cluster master", - (g_cluster.localNode == wdNode)? "local":"remote", + (g_cluster.localNode == wdNode) ? "local" : "remote", wdNode->nodeName))); g_cluster.clusterMasterInfo.masterNode = wdNode; } } -static WatchdogNode* getMasterWatchdogNode(void) +static WatchdogNode * getMasterWatchdogNode(void) { return g_cluster.clusterMasterInfo.masterNode; } -static int standby_node_join_cluster(WatchdogNode* wdNode) +static int +standby_node_join_cluster(WatchdogNode * wdNode) { if (get_local_node_state() == WD_COORDINATOR) { - int i; + int i; + /* First check if the node is already in the List */ - for ( i = 0; i < g_cluster.clusterMasterInfo.standby_nodes_count; i++) + for (i = 0; i < g_cluster.clusterMasterInfo.standby_nodes_count; i++) { - WatchdogNode* node = g_cluster.clusterMasterInfo.standbyNodes[i]; + WatchdogNode *node = g_cluster.clusterMasterInfo.standbyNodes[i]; + if (node && node == wdNode) { /* The node is already in the standby list */ @@ -6802,7 +7114,7 @@ static int standby_node_join_cluster(WatchdogNode* wdNode) } /* okay the node is not in the list */ ereport(LOG, - (errmsg("adding watchdog node \"%s\" to the standby list",wdNode->nodeName))); + (errmsg("adding watchdog node \"%s\" to the standby list", wdNode->nodeName))); g_cluster.clusterMasterInfo.standbyNodes[g_cluster.clusterMasterInfo.standby_nodes_count] = wdNode; g_cluster.clusterMasterInfo.standby_nodes_count++; } @@ -6810,30 +7122,34 @@ static int standby_node_join_cluster(WatchdogNode* wdNode) return g_cluster.clusterMasterInfo.standby_nodes_count; } -static int standby_node_left_cluster(WatchdogNode* wdNode) +static int +standby_node_left_cluster(WatchdogNode * wdNode) { if (get_local_node_state() == WD_COORDINATOR) { - int i; - bool removed = false; - int standby_nodes_count = g_cluster.clusterMasterInfo.standby_nodes_count; - for ( i = 0; i < standby_nodes_count; i++) + int i; + bool removed = false; + int standby_nodes_count = g_cluster.clusterMasterInfo.standby_nodes_count; + + for (i = 0; i < standby_nodes_count; i++) { - WatchdogNode* node = g_cluster.clusterMasterInfo.standbyNodes[i]; + WatchdogNode *node = g_cluster.clusterMasterInfo.standbyNodes[i]; + if (node) { if (removed) { /* move this to previous index */ - g_cluster.clusterMasterInfo.standbyNodes[i -1] = node; + g_cluster.clusterMasterInfo.standbyNodes[i - 1] = node; g_cluster.clusterMasterInfo.standbyNodes[i] = NULL; } else if (node == wdNode) { - /* okay we have found the node in the list. + /* + * okay we have found the node in the list. */ ereport(LOG, - (errmsg("removing watchdog node \"%s\" from the standby list",wdNode->nodeName))); + (errmsg("removing watchdog node \"%s\" from the standby list", wdNode->nodeName))); g_cluster.clusterMasterInfo.standbyNodes[i] = NULL; g_cluster.clusterMasterInfo.standby_nodes_count--; @@ -6846,17 +7162,18 @@ static int standby_node_left_cluster(WatchdogNode* wdNode) return g_cluster.clusterMasterInfo.standby_nodes_count; } -static void clear_standby_nodes_list(void) +static void +clear_standby_nodes_list(void) { - int i; + int i; + ereport(DEBUG1, (errmsg("removing all watchdog nodes from the standby list"), - errdetail("standby list contains %d nodes",g_cluster.clusterMasterInfo.standby_nodes_count))); - for ( i = 0; i < g_cluster.remoteNodeCount; i++) + errdetail("standby list contains %d nodes", g_cluster.clusterMasterInfo.standby_nodes_count))); + for (i = 0; i < g_cluster.remoteNodeCount; i++) { g_cluster.clusterMasterInfo.standbyNodes[i] = NULL; } g_cluster.clusterMasterInfo.standby_nodes_count = 0; g_cluster.localNode->standby_nodes_count = 0; } - diff --git a/src/watchdog/wd_commands.c b/src/watchdog/wd_commands.c index 2d0bee7c9..9b2e4791d 100644 --- a/src/watchdog/wd_commands.c +++ b/src/watchdog/wd_commands.c @@ -49,39 +49,41 @@ #include "watchdog/wd_ipc_commands.h" #include "watchdog/wd_ipc_defines.h" -#define WD_DEFAULT_IPC_COMMAND_TIMEOUT 8 /* default number of seconds to wait for IPC command results*/ +#define WD_DEFAULT_IPC_COMMAND_TIMEOUT 8 /* default number of seconds to + * wait for IPC command results */ #define WD_INTERLOCK_WAIT_MSEC 500 #define WD_INTERLOCK_TIMEOUT_SEC 10 #define WD_INTERLOCK_WAIT_COUNT ((int) ((WD_INTERLOCK_TIMEOUT_SEC * 1000)/WD_INTERLOCK_WAIT_MSEC)) -static void FreeCmdResult(WDIPCCmdResult* res); -static char* get_wd_failover_state_json(bool start); +static void FreeCmdResult(WDIPCCmdResult * res); +static char *get_wd_failover_state_json(bool start); -static int open_wd_command_sock(bool throw_error); -static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *result, unsigned int *wd_failover_id); -static WDFailoverCMDResults wd_issue_failover_command(char* func_name, int *node_id_set, int count, unsigned char flags); +static int open_wd_command_sock(bool throw_error); +static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult * result, unsigned int *wd_failover_id); +static WDFailoverCMDResults wd_issue_failover_command(char *func_name, int *node_id_set, int count, unsigned char flags); /* shared memory variables */ -char *watchdog_ipc_address = NULL; -bool *watchdog_require_cleanup = NULL; /* shared memory variable set to true - * when watchdog process terminates abnormally - */ -bool *watchdog_node_escalated = NULL; /* shared memory variable set to true - * when watchdog process has performed escalation - */ -unsigned int *ipc_shared_key = NULL; /* key lives in shared memory - * used to identify the ipc internal - * clients - */ -void wd_ipc_initialize_data(void) +char *watchdog_ipc_address = NULL; +bool *watchdog_require_cleanup = NULL; /* shared memory variable set + * to true when watchdog + * process terminates + * abnormally */ +bool *watchdog_node_escalated = NULL; /* shared memory variable set to + * true when watchdog process has + * performed escalation */ +unsigned int *ipc_shared_key = NULL; /* key lives in shared memory used to + * identify the ipc internal clients */ +void +wd_ipc_initialize_data(void) { if (watchdog_ipc_address == NULL) { - char wd_ipc_sock_addr[255]; + char wd_ipc_sock_addr[255]; + snprintf(wd_ipc_sock_addr, sizeof(wd_ipc_sock_addr), "%s/.s.PGPOOLWD_CMD.%d", pool_config->wd_ipc_socket_dir, pool_config->wd_port); - watchdog_ipc_address = pool_shared_memory_create(strlen(wd_ipc_sock_addr) +1); + watchdog_ipc_address = pool_shared_memory_create(strlen(wd_ipc_sock_addr) + 1); strcpy(watchdog_ipc_address, wd_ipc_sock_addr); } @@ -89,8 +91,9 @@ void wd_ipc_initialize_data(void) { ipc_shared_key = pool_shared_memory_create(sizeof(unsigned int)); *ipc_shared_key = 0; - while (*ipc_shared_key == 0) { - pool_random_salt((char*)ipc_shared_key); + while (*ipc_shared_key == 0) + { + pool_random_salt((char *) ipc_shared_key); } } @@ -107,10 +110,12 @@ void wd_ipc_initialize_data(void) } } -WD_STATES get_watchdog_local_node_state(void) +WD_STATES +get_watchdog_local_node_state(void) { - WD_STATES ret = WD_DEAD; + WD_STATES ret = WD_DEAD; WDGenericData *state = get_wd_runtime_variable_value(WD_RUNTIME_VAR_WD_STATE); + if (state == NULL) { ereport(LOG, @@ -126,15 +131,17 @@ WD_STATES get_watchdog_local_node_state(void) pfree(state); return WD_DEAD; } - ret = (WD_STATES)state->data.intVal; + ret = (WD_STATES) state->data.intVal; pfree(state); return ret; } -int get_watchdog_quorum_state(void) +int +get_watchdog_quorum_state(void) { - WD_STATES ret = WD_DEAD; + WD_STATES ret = WD_DEAD; WDGenericData *state = get_wd_runtime_variable_value(WD_RUNTIME_VAR_QUORUM_STATE); + if (state == NULL) { ereport(LOG, @@ -150,48 +157,56 @@ int get_watchdog_quorum_state(void) pfree(state); return WD_DEAD; } - ret = (WD_STATES)state->data.intVal; + ret = (WD_STATES) state->data.intVal; pfree(state); return ret; } -char* get_watchdog_ipc_address(void) +char * +get_watchdog_ipc_address(void) { return watchdog_ipc_address; } -unsigned int* get_ipc_shared_key(void) +unsigned int * +get_ipc_shared_key(void) { return ipc_shared_key; } -void set_watchdog_process_needs_cleanup(void) +void +set_watchdog_process_needs_cleanup(void) { *watchdog_require_cleanup = true; } -void reset_watchdog_process_needs_cleanup(void) +void +reset_watchdog_process_needs_cleanup(void) { *watchdog_require_cleanup = false; } -bool get_watchdog_process_needs_cleanup(void) +bool +get_watchdog_process_needs_cleanup(void) { return *watchdog_require_cleanup; } -void set_watchdog_node_escalated(void) +void +set_watchdog_node_escalated(void) { *watchdog_node_escalated = true; } -void reset_watchdog_node_escalated(void) +void +reset_watchdog_node_escalated(void) { *watchdog_node_escalated = false; } -bool get_watchdog_node_escalation_state(void) +bool +get_watchdog_node_escalation_state(void) { return *watchdog_node_escalated; } @@ -208,14 +223,17 @@ bool get_watchdog_node_escalation_state(void) * blocking: send true if caller wants to wait for the results * when blocking is false the timeout_sec is ignored */ -WDIPCCmdResult* -issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, bool blocking) +WDIPCCmdResult * +issue_command_to_watchdog(char type, int timeout_sec, char *data, int data_len, bool blocking) { - struct timeval start_time,tv; - int sock; - WDIPCCmdResult* result = NULL; - char res_type = 'P'; - int res_length, len; + struct timeval start_time, + tv; + int sock; + WDIPCCmdResult *result = NULL; + char res_type = 'P'; + int res_length, + len; + gettimeofday(&start_time, NULL); /* open the watchdog command socket for IPC */ @@ -248,8 +266,9 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, if (blocking) { /* if we are asked to wait for results */ - fd_set fds; + fd_set fds; struct timeval *timeout_st = NULL; + if (timeout_sec > 0) { tv.tv_sec = timeout_sec; @@ -257,11 +276,12 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, timeout_st = &tv; } FD_ZERO(&fds); - FD_SET(sock,&fds); + FD_SET(sock, &fds); for (;;) { - int select_res; - select_res = select(sock+1,&fds,NULL,NULL,timeout_st); + int select_res; + + select_res = select(sock + 1, &fds, NULL, NULL, timeout_st); if (select_res == 0) { close(sock); @@ -276,19 +296,19 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, if (errno == EAGAIN || errno == EINTR) continue; ereport(WARNING, - (errmsg("error reading from IPC command socket for ipc command %c",type), - errdetail("select system call failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading from IPC command socket for ipc command %c", type), + errdetail("select system call failed with error \"%s\"", strerror(errno)))); close(sock); return NULL; } if (select_res > 0) { /* read the result type char */ - if (socket_read(sock, &res_type, 1 ,0) <=0) + if (socket_read(sock, &res_type, 1, 0) <= 0) { ereport(WARNING, - (errmsg("error reading from IPC command socket for ipc command %c",type), - errdetail("read from socket failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading from IPC command socket for ipc command %c", type), + errdetail("read from socket failed with error \"%s\"", strerror(errno)))); close(sock); return result; } @@ -296,8 +316,8 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, if (socket_read(sock, &res_length, sizeof(int), 0) <= 0) { ereport(WARNING, - (errmsg("error reading from IPC command socket for ipc command %c",type), - errdetail("read from socket failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading from IPC command socket for ipc command %c", type), + errdetail("read from socket failed with error \"%s\"", strerror(errno)))); close(sock); return result; } @@ -315,8 +335,8 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, pfree(result->data); pfree(result); ereport(DEBUG1, - (errmsg("error reading from IPC command socket for ipc command %c",type), - errdetail("read from socket failed with error \"%s\"",strerror(errno)))); + (errmsg("error reading from IPC command socket for ipc command %c", type), + errdetail("read from socket failed with error \"%s\"", strerror(errno)))); close(sock); return NULL; } @@ -327,7 +347,8 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, } else { - /* For non blocking mode if we are sucessful in sending the command + /* + * For non blocking mode if we are sucessful in sending the command * that means the command is success */ result = palloc0(sizeof(WDIPCCmdResult)); @@ -341,21 +362,23 @@ issue_command_to_watchdog(char type, int timeout_sec, char* data, int data_len, * Function gets the runtime value of watchdog varibale using the * watchdog IPC */ -WDGenericData *get_wd_runtime_variable_value(char *varName) +WDGenericData * +get_wd_runtime_variable_value(char *varName) { unsigned int *shared_key = get_ipc_shared_key(); - char *data = get_simple_request_json(WD_JSON_KEY_VARIABLE_NAME,varName, - shared_key?*shared_key:0,pool_config->wd_authkey); + char *data = get_simple_request_json(WD_JSON_KEY_VARIABLE_NAME, varName, + shared_key ? *shared_key : 0, pool_config->wd_authkey); WDIPCCmdResult *result = issue_command_to_watchdog(WD_GET_RUNTIME_VARIABLE_VALUE, WD_DEFAULT_IPC_COMMAND_TIMEOUT, data, strlen(data), true); + pfree(data); if (result == NULL) { ereport(WARNING, - (errmsg("get runtime variable value from watchdog failed"), + (errmsg("get runtime variable value from watchdog failed"), errdetail("issue command to watchdog returned NULL"))); return NULL; } @@ -364,7 +387,7 @@ WDGenericData *get_wd_runtime_variable_value(char *varName) ereport(WARNING, (errmsg("get runtime variable value from watchdog failed"), errdetail("watchdog cluster is not in stable state"), - errhint("try again when the cluster is fully initialized"))); + errhint("try again when the cluster is fully initialized"))); FreeCmdResult(result); return NULL; } @@ -390,84 +413,89 @@ WDGenericData *get_wd_runtime_variable_value(char *varName) return NULL; } - if (json_get_int_value_for_key(root, WD_JSON_KEY_VALUE_DATA_TYPE, (int*)&dayaType)) + if (json_get_int_value_for_key(root, WD_JSON_KEY_VALUE_DATA_TYPE, (int *) &dayaType)) { FreeCmdResult(result); json_value_free(root); return NULL; } - switch (dayaType) { + switch (dayaType) + { case VALUE_DATA_TYPE_INT: - { - int intVal; - if (json_get_int_value_for_key(root, WD_JSON_KEY_VALUE_DATA, &intVal)) - { - ereport(WARNING, - (errmsg("get runtime variable value from watchdog failed"), - errdetail("unable to get INT value from JSON data returned by watchdog"))); - } - else { - genData = palloc(sizeof(WDGenericData)); - genData->valueType = dayaType; - genData->data.intVal = intVal; + int intVal; + + if (json_get_int_value_for_key(root, WD_JSON_KEY_VALUE_DATA, &intVal)) + { + ereport(WARNING, + (errmsg("get runtime variable value from watchdog failed"), + errdetail("unable to get INT value from JSON data returned by watchdog"))); + } + else + { + genData = palloc(sizeof(WDGenericData)); + genData->valueType = dayaType; + genData->data.intVal = intVal; + } } - } break; case VALUE_DATA_TYPE_LONG: - { - long longVal; - if (json_get_long_value_for_key(root, WD_JSON_KEY_VALUE_DATA, &longVal)) - { - ereport(WARNING, - (errmsg("get runtime variable value from watchdog failed"), - errdetail("unable to get LONG value from JSON data returned by watchdog"))); - } - else { - genData = palloc(sizeof(WDGenericData)); - genData->valueType = dayaType; - genData->data.longVal = longVal; + long longVal; + + if (json_get_long_value_for_key(root, WD_JSON_KEY_VALUE_DATA, &longVal)) + { + ereport(WARNING, + (errmsg("get runtime variable value from watchdog failed"), + errdetail("unable to get LONG value from JSON data returned by watchdog"))); + } + else + { + genData = palloc(sizeof(WDGenericData)); + genData->valueType = dayaType; + genData->data.longVal = longVal; + } } - } break; case VALUE_DATA_TYPE_BOOL: - { - bool boolVal; - if (json_get_bool_value_for_key(root, WD_JSON_KEY_VALUE_DATA, &boolVal)) - { - ereport(WARNING, - (errmsg("get runtime variable value from watchdog failed"), - errdetail("unable to get BOOL value from JSON data returned by watchdog"))); - } - else { - genData = palloc(sizeof(WDGenericData)); - genData->valueType = dayaType; - genData->data.boolVal = boolVal; + bool boolVal; + + if (json_get_bool_value_for_key(root, WD_JSON_KEY_VALUE_DATA, &boolVal)) + { + ereport(WARNING, + (errmsg("get runtime variable value from watchdog failed"), + errdetail("unable to get BOOL value from JSON data returned by watchdog"))); + } + else + { + genData = palloc(sizeof(WDGenericData)); + genData->valueType = dayaType; + genData->data.boolVal = boolVal; + } } - } break; case VALUE_DATA_TYPE_STRING: - { - char *ptr = json_get_string_value_for_key(root, WD_JSON_KEY_VALUE_DATA); - if (ptr == NULL) - { - ereport(WARNING, - (errmsg("get runtime variable value from watchdog failed"), - errdetail("unable to get STRING value from JSON data returned by watchdog"))); - } - else { - genData = palloc(sizeof(WDGenericData)); - genData->valueType = dayaType; - genData->data.stringVal = pstrdup(ptr); + char *ptr = json_get_string_value_for_key(root, WD_JSON_KEY_VALUE_DATA); + + if (ptr == NULL) + { + ereport(WARNING, + (errmsg("get runtime variable value from watchdog failed"), + errdetail("unable to get STRING value from JSON data returned by watchdog"))); + } + else + { + genData = palloc(sizeof(WDGenericData)); + genData->valueType = dayaType; + genData->data.stringVal = pstrdup(ptr); + } } - } break; default: @@ -492,30 +520,32 @@ WDGenericData *get_wd_runtime_variable_value(char *varName) * function gets the PG backend status of all attached nodes from * the master watchdog node. */ -WDPGBackendStatus* get_pg_backend_status_from_master_wd_node(void) +WDPGBackendStatus * +get_pg_backend_status_from_master_wd_node(void) { unsigned int *shared_key = get_ipc_shared_key(); - char *data = get_data_request_json(WD_DATE_REQ_PG_BACKEND_DATA, - shared_key?*shared_key:0,pool_config->wd_authkey); + char *data = get_data_request_json(WD_DATE_REQ_PG_BACKEND_DATA, + shared_key ? *shared_key : 0, pool_config->wd_authkey); WDIPCCmdResult *result = issue_command_to_watchdog(WD_GET_MASTER_DATA_REQUEST, WD_DEFAULT_IPC_COMMAND_TIMEOUT, data, strlen(data), true); + pfree(data); if (result == NULL) { ereport(WARNING, - (errmsg("get backend node status from master watchdog failed"), + (errmsg("get backend node status from master watchdog failed"), errdetail("issue command to watchdog returned NULL"))); return NULL; } if (result->type == WD_IPC_CMD_CLUSTER_IN_TRAN) { ereport(WARNING, - (errmsg("get backend node status from master watchdog failed"), + (errmsg("get backend node status from master watchdog failed"), errdetail("watchdog cluster is not in stable state"), - errhint("try again when the cluster is fully initialized"))); + errhint("try again when the cluster is fully initialized"))); FreeCmdResult(result); return NULL; } @@ -529,10 +559,11 @@ WDPGBackendStatus* get_pg_backend_status_from_master_wd_node(void) } else if (result->type == WD_IPC_CMD_RESULT_OK) { - WDPGBackendStatus* backendStatus = get_pg_backend_node_status_from_json(result->data, result->length); + WDPGBackendStatus *backendStatus = get_pg_backend_node_status_from_json(result->data, result->length); + /* - * Watchdog returns the zero length data when the node itself is a master - * watchdog node + * Watchdog returns the zero length data when the node itself is a + * master watchdog node */ if (result->length <= 0) { @@ -541,14 +572,14 @@ WDPGBackendStatus* get_pg_backend_status_from_master_wd_node(void) } else { - backendStatus = get_pg_backend_node_status_from_json(result->data, result->length); + backendStatus = get_pg_backend_node_status_from_json(result->data, result->length); } FreeCmdResult(result); return backendStatus; } ereport(WARNING, - (errmsg("get backend node status from master watchdog failed"))); + (errmsg("get backend node status from master watchdog failed"))); FreeCmdResult(result); return NULL; } @@ -556,21 +587,22 @@ WDPGBackendStatus* get_pg_backend_status_from_master_wd_node(void) WdCommandResult wd_start_recovery(void) { - char type; + char type; unsigned int *shared_key = get_ipc_shared_key(); - char* func = get_wd_node_function_json(WD_FUNCTION_START_RECOVERY, NULL,0, 0, - shared_key?*shared_key:0,pool_config->wd_authkey); + char *func = get_wd_node_function_json(WD_FUNCTION_START_RECOVERY, NULL, 0, 0, + shared_key ? *shared_key : 0, pool_config->wd_authkey); WDIPCCmdResult *result = issue_command_to_watchdog(WD_IPC_ONLINE_RECOVERY_COMMAND, pool_config->recovery_timeout, func, strlen(func), true); + pfree(func); - + if (result == NULL) { ereport(WARNING, - (errmsg("start recovery command lock failed"), + (errmsg("start recovery command lock failed"), errdetail("issue command to watchdog returned NULL"))); return COMMAND_FAILED; } @@ -580,15 +612,15 @@ wd_start_recovery(void) if (type == WD_IPC_CMD_CLUSTER_IN_TRAN) { ereport(WARNING, - (errmsg("start recovery command lock failed"), + (errmsg("start recovery command lock failed"), errdetail("watchdog cluster is not in stable state"), - errhint("try again when the cluster is fully initialized"))); + errhint("try again when the cluster is fully initialized"))); return CLUSTER_IN_TRANSATIONING; } else if (type == WD_IPC_CMD_TIMEOUT) { ereport(WARNING, - (errmsg("start recovery command lock failed"), + (errmsg("start recovery command lock failed"), errdetail("ipc command timeout"))); return COMMAND_TIMEOUT; } @@ -602,26 +634,27 @@ wd_start_recovery(void) WdCommandResult wd_end_recovery(void) { - char type; + char type; unsigned int *shared_key = get_ipc_shared_key(); - char* func = get_wd_node_function_json(WD_FUNCTION_END_RECOVERY, NULL, 0, 0, - shared_key?*shared_key:0,pool_config->wd_authkey); + char *func = get_wd_node_function_json(WD_FUNCTION_END_RECOVERY, NULL, 0, 0, + shared_key ? *shared_key : 0, pool_config->wd_authkey); + - WDIPCCmdResult *result = issue_command_to_watchdog(WD_IPC_ONLINE_RECOVERY_COMMAND, WD_DEFAULT_IPC_COMMAND_TIMEOUT, func, strlen(func), true); + pfree(func); - + if (result == NULL) { ereport(WARNING, - (errmsg("end recovery command lock failed"), + (errmsg("end recovery command lock failed"), errdetail("issue command to watchdog returned NULL"))); return COMMAND_FAILED; } - + type = result->type; FreeCmdResult(result); @@ -630,13 +663,13 @@ wd_end_recovery(void) ereport(WARNING, (errmsg("end recovery command lock failed"), errdetail("watchdog cluster is not in stable state"), - errhint("try again when the cluster is fully initialized"))); + errhint("try again when the cluster is fully initialized"))); return CLUSTER_IN_TRANSATIONING; } else if (type == WD_IPC_CMD_TIMEOUT) { ereport(WARNING, - (errmsg("end recovery command lock failed"), + (errmsg("end recovery command lock failed"), errdetail("ipc command timeout"))); return COMMAND_TIMEOUT; } @@ -647,17 +680,18 @@ wd_end_recovery(void) return COMMAND_FAILED; } -static char* get_wd_failover_state_json(bool start) +static char * +get_wd_failover_state_json(bool start) { - char* json_str; - JsonNode* jNode = jw_create_with_object(true); + char *json_str; + JsonNode *jNode = jw_create_with_object(true); unsigned int *shared_key = get_ipc_shared_key(); - jw_put_int(jNode, WD_IPC_SHARED_KEY, shared_key?*shared_key:0); /* put the shared key*/ + jw_put_int(jNode, WD_IPC_SHARED_KEY, shared_key ? *shared_key : 0); /* put the shared key */ if (pool_config->wd_authkey != NULL && strlen(pool_config->wd_authkey) > 0) - jw_put_string(jNode, WD_IPC_AUTH_KEY, pool_config->wd_authkey); /* put the auth key*/ + jw_put_string(jNode, WD_IPC_AUTH_KEY, pool_config->wd_authkey); /* put the auth key */ - jw_put_int(jNode, "FailoverFuncState", start?0:1); + jw_put_int(jNode, "FailoverFuncState", start ? 0 : 1); jw_finish_document(jNode); json_str = pstrdup(jw_get_json_string(jNode)); jw_destroy(jNode); @@ -670,7 +704,7 @@ wd_send_failover_func_status_command(bool start) WDFailoverCMDResults res; unsigned int failover_id; - char* json_data = get_wd_failover_state_json(start); + char *json_data = get_wd_failover_state_json(start); WDIPCCmdResult *result = issue_command_to_watchdog(WD_FAILOVER_INDICATION ,pool_config->recovery_timeout, @@ -684,7 +718,7 @@ wd_send_failover_func_status_command(bool start) return res; } -static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *result, unsigned int *wd_failover_id) +static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult * result, unsigned int *wd_failover_id) { if (result == NULL) return FAILOVER_RES_ERROR; @@ -692,7 +726,7 @@ static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *res if (result == NULL) { ereport(WARNING, - (errmsg("failover command on watchdog failed"), + (errmsg("failover command on watchdog failed"), errdetail("issue command to watchdog returned NULL"))); return FAILOVER_RES_ERROR; } @@ -701,7 +735,7 @@ static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *res ereport(WARNING, (errmsg("failover command on watchdog failed"), errdetail("watchdog cluster is not in stable state"), - errhint("try again when the cluster is fully initialized"))); + errhint("try again when the cluster is fully initialized"))); return FAILOVER_RES_TRANSITION; } else if (result->type == WD_IPC_CMD_TIMEOUT) @@ -716,7 +750,7 @@ static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *res WDFailoverCMDResults res = FAILOVER_RES_ERROR; json_value *root; - root = json_parse(result->data,result->length); + root = json_parse(result->data, result->length); /* The root node must be object */ if (root == NULL || root->type != json_object) { @@ -724,12 +758,12 @@ static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *res (errmsg("unable to parse json data from failover command result"))); return res; } - if (root && json_get_int_value_for_key(root, WD_FAILOVER_RESULT_KEY, (int*)&res)) + if (root && json_get_int_value_for_key(root, WD_FAILOVER_RESULT_KEY, (int *) &res)) { json_value_free(root); return FAILOVER_RES_ERROR; } - if (root && json_get_int_value_for_key(root, WD_FAILOVER_ID_KEY, (int*)wd_failover_id)) + if (root && json_get_int_value_for_key(root, WD_FAILOVER_ID_KEY, (int *) wd_failover_id)) { json_value_free(root); return FAILOVER_RES_ERROR; @@ -740,19 +774,20 @@ static WDFailoverCMDResults wd_get_failover_result_from_data(WDIPCCmdResult *res } static WDFailoverCMDResults -wd_issue_failover_command(char* func_name, int *node_id_set, int count, unsigned char flags) +wd_issue_failover_command(char *func_name, int *node_id_set, int count, unsigned char flags) { WDFailoverCMDResults res; - char* func; + char *func; unsigned int *shared_key = get_ipc_shared_key(); unsigned int wd_failover_id; - - func = get_wd_node_function_json(func_name,node_id_set, count, flags, - shared_key?*shared_key:0,pool_config->wd_authkey); - WDIPCCmdResult *result = issue_command_to_watchdog(WD_IPC_FAILOVER_COMMAND , + func = get_wd_node_function_json(func_name, node_id_set, count, flags, + shared_key ? *shared_key : 0, pool_config->wd_authkey); + + WDIPCCmdResult *result = issue_command_to_watchdog(WD_IPC_FAILOVER_COMMAND, WD_DEFAULT_IPC_COMMAND_TIMEOUT, func, strlen(func), true); + pfree(func); res = wd_get_failover_result_from_data(result, &wd_failover_id); FreeCmdResult(result); @@ -798,57 +833,60 @@ wd_send_failback_request(int node_id, unsigned char flags) * Function returns the JSON of watchdog nodes * pass nodeID = -1 to get list of all nodes */ -char* wd_get_watchdog_nodes(int nodeID) +char * +wd_get_watchdog_nodes(int nodeID) { WDIPCCmdResult *result; - char* json_str; + char *json_str; unsigned int *shared_key = get_ipc_shared_key(); - JsonNode* jNode = jw_create_with_object(true); + JsonNode *jNode = jw_create_with_object(true); + jw_put_int(jNode, "NodeID", nodeID); - jw_put_int(jNode, WD_IPC_SHARED_KEY, shared_key?*shared_key:0); /* put the shared key*/ + jw_put_int(jNode, WD_IPC_SHARED_KEY, shared_key ? *shared_key : 0); /* put the shared key */ if (pool_config->wd_authkey != NULL && strlen(pool_config->wd_authkey) > 0) - jw_put_string(jNode, WD_IPC_AUTH_KEY, pool_config->wd_authkey); /* put the auth key*/ + jw_put_string(jNode, WD_IPC_AUTH_KEY, pool_config->wd_authkey); /* put the auth key */ jw_finish_document(jNode); - + json_str = jw_get_json_string(jNode); - + result = issue_command_to_watchdog(WD_GET_NODES_LIST_COMMAND ,WD_DEFAULT_IPC_COMMAND_TIMEOUT, json_str, strlen(json_str), true); - + jw_destroy(jNode); - + if (result == NULL) { ereport(WARNING, - (errmsg("get watchdog nodes command failed"), + (errmsg("get watchdog nodes command failed"), errdetail("issue command to watchdog returned NULL"))); return NULL; } else if (result->type == WD_IPC_CMD_CLUSTER_IN_TRAN) { ereport(WARNING, - (errmsg("get watchdog nodes command failed"), + (errmsg("get watchdog nodes command failed"), errdetail("watchdog cluster is not in stable state"), - errhint("try again when the cluster is fully initialized"))); + errhint("try again when the cluster is fully initialized"))); FreeCmdResult(result); return NULL; } else if (result->type == WD_IPC_CMD_TIMEOUT) { ereport(WARNING, - (errmsg("get watchdog nodes command failed"), + (errmsg("get watchdog nodes command failed"), errdetail("ipc command timeout"))); FreeCmdResult(result); return NULL; } else if (result->type == WD_IPC_CMD_RESULT_OK) { - char* data = result->data; + char *data = result->data; + /* do not free the result->data, Save the data copy */ pfree(result); return data; @@ -860,15 +898,15 @@ char* wd_get_watchdog_nodes(int nodeID) static int open_wd_command_sock(bool throw_error) { - size_t len; + size_t len; struct sockaddr_un addr; - int sock = -1; - + int sock = -1; + /* We use unix domain stream sockets for the purpose */ if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { /* socket create failed */ - ereport(throw_error? ERROR:LOG, + ereport(throw_error ? ERROR : LOG, (errmsg("failed to connect to watchdog command server socket"), errdetail("connect on \"%s\" failed with reason: \"%s\"", addr.sun_path, strerror(errno)))); return -1; @@ -876,13 +914,13 @@ open_wd_command_sock(bool throw_error) memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path),"%s",watchdog_ipc_address); + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", watchdog_ipc_address); len = sizeof(struct sockaddr_un); - + if (connect(sock, (struct sockaddr *) &addr, len) == -1) { close(sock); - ereport(throw_error? ERROR:LOG, + ereport(throw_error ? ERROR : LOG, (errmsg("failed to connect to watchdog command server socket"), errdetail("connect on \"%s\" failed with reason: \"%s\"", addr.sun_path, strerror(errno)))); return -1; @@ -890,14 +928,16 @@ open_wd_command_sock(bool throw_error) return sock; } -WDFailoverCMDResults wd_failover_start(void) +WDFailoverCMDResults +wd_failover_start(void) { if (pool_config->use_watchdog) return wd_send_failover_func_status_command(true); return FAILOVER_RES_PROCEED; } -WDFailoverCMDResults wd_failover_end(void) +WDFailoverCMDResults +wd_failover_end(void) { if (pool_config->use_watchdog) return wd_send_failover_func_status_command(false); @@ -905,12 +945,13 @@ WDFailoverCMDResults wd_failover_end(void) } -static void FreeCmdResult(WDIPCCmdResult* res) +static void +FreeCmdResult(WDIPCCmdResult * res) { if (res == NULL) return; if (res->data) pfree(res->data); - pfree (res); + pfree(res); } diff --git a/src/watchdog/wd_escalation.c b/src/watchdog/wd_escalation.c index 239bc8474..40fd5a99f 100644 --- a/src/watchdog/wd_escalation.c +++ b/src/watchdog/wd_escalation.c @@ -43,8 +43,8 @@ static void wd_exit(int exit_signo) { - sigset_t mask; - + sigset_t mask; + sigemptyset(&mask); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGINT); @@ -61,7 +61,8 @@ wd_exit(int exit_signo) pid_t fork_escalation_process(void) { - pid_t pid; + pid_t pid; + pid = fork(); if (pid != 0) { @@ -76,7 +77,7 @@ fork_escalation_process(void) POOL_SETMASK(&UnBlockSig); init_ps_display("", "", "", ""); - + pool_signal(SIGTERM, wd_exit); pool_signal(SIGINT, wd_exit); pool_signal(SIGQUIT, wd_exit); @@ -85,32 +86,32 @@ fork_escalation_process(void) pool_signal(SIGPIPE, SIG_IGN); MemoryContextSwitchTo(TopMemoryContext); - - set_ps_display("watchdog escalation",false); + + set_ps_display("watchdog escalation", false); ereport(LOG, (errmsg("watchdog: escalation started"))); + /* - * STEP 1 - * clear shared memory cache + * STEP 1 clear shared memory cache */ if (pool_config->memory_cache_enabled && pool_is_shmem_cache() && pool_config->clear_memqcache_on_escalation) { ereport(LOG, - (errmsg("watchdog escalation"), + (errmsg("watchdog escalation"), errdetail("clearing all the query cache on shared memory"))); - + pool_clear_memory_cache(); } /* - * STEP 2 - * execute escalation command provided by user in pgpool conf file + * STEP 2 execute escalation command provided by user in pgpool conf file */ if (strlen(pool_config->wd_escalation_command)) { - int r = system(pool_config->wd_escalation_command); + int r = system(pool_config->wd_escalation_command); + if (WIFEXITED(r)) { if (WEXITSTATUS(r) == EXIT_SUCCESS) @@ -130,14 +131,13 @@ fork_escalation_process(void) } /* - * STEP 3 - * bring up the delegate IP + * STEP 3 bring up the delegate IP */ if (strlen(pool_config->delegate_IP) != 0) { if (wd_IP_up() != WD_OK) ereport(WARNING, - (errmsg("watchdog escalation failed to acquire delegate IP"))); + (errmsg("watchdog escalation failed to acquire delegate IP"))); } exit(0); @@ -149,7 +149,7 @@ fork_escalation_process(void) pid_t fork_plunging_process(void) { - pid_t pid; + pid_t pid; pid = fork(); if (pid != 0) @@ -161,32 +161,33 @@ fork_plunging_process(void) } on_exit_reset(); processType = PT_WATCHDOG_UTILITY; - + POOL_SETMASK(&UnBlockSig); - + init_ps_display("", "", "", ""); - + pool_signal(SIGTERM, wd_exit); pool_signal(SIGINT, wd_exit); pool_signal(SIGQUIT, wd_exit); pool_signal(SIGCHLD, SIG_DFL); pool_signal(SIGHUP, SIG_IGN); pool_signal(SIGPIPE, SIG_IGN); - + MemoryContextSwitchTo(TopMemoryContext); - - set_ps_display("watchdog de-escalation",false); - + + set_ps_display("watchdog de-escalation", false); + ereport(LOG, (errmsg("watchdog: de-escalation started"))); - + /* - * STEP 1 - * execute de-escalation command provided by user in pgpool conf file + * STEP 1 execute de-escalation command provided by user in pgpool conf + * file */ if (strlen(pool_config->wd_de_escalation_command)) { - int r = system(pool_config->wd_de_escalation_command); + int r = system(pool_config->wd_de_escalation_command); + if (WIFEXITED(r)) { if (WEXITSTATUS(r) == EXIT_SUCCESS) @@ -204,12 +205,11 @@ fork_plunging_process(void) (errmsg("watchdog de-escalation command exit abnormally"))); } } - + /* - * STEP 2 - * bring down the delegate IP + * STEP 2 bring down the delegate IP */ - + if (strlen(pool_config->delegate_IP) != 0) { if (wd_IP_down() != WD_OK) diff --git a/src/watchdog/wd_heartbeat.c b/src/watchdog/wd_heartbeat.c index 4f12b94cc..266b68a96 100644 --- a/src/watchdog/wd_heartbeat.c +++ b/src/watchdog/wd_heartbeat.c @@ -57,50 +57,51 @@ /* * heartbeat packet */ -typedef struct { - char from[WD_MAX_HOST_NAMELEN]; - int from_pgpool_port; +typedef struct +{ + char from[WD_MAX_HOST_NAMELEN]; + int from_pgpool_port; struct timeval send_time; - char hash[WD_AUTH_HASH_LEN + 1]; -} WdHbPacket; + char hash[WD_AUTH_HASH_LEN + 1]; +} WdHbPacket; static RETSIGTYPE hb_sender_exit(int sig); static RETSIGTYPE hb_receiver_exit(int sig); -static int hton_wd_hb_packet(WdHbPacket *to, WdHbPacket *from); -static int ntoh_wd_hb_packet(WdHbPacket *to, WdHbPacket *from); -static int packet_to_string_hb(WdHbPacket *pkt, char * str, int maxlen); +static int hton_wd_hb_packet(WdHbPacket * to, WdHbPacket * from); +static int ntoh_wd_hb_packet(WdHbPacket * to, WdHbPacket * from); +static int packet_to_string_hb(WdHbPacket * pkt, char *str, int maxlen); static void wd_set_reuseport(int sock); -static int wd_create_hb_send_socket(WdHbIf * hb_if); -static int wd_create_hb_recv_socket(WdHbIf * hb_if); +static int wd_create_hb_send_socket(WdHbIf * hb_if); +static int wd_create_hb_recv_socket(WdHbIf * hb_if); -static void wd_hb_send(int sock, WdHbPacket * pkt, int len, const char * destination, const int dest_port); +static void wd_hb_send(int sock, WdHbPacket * pkt, int len, const char *destination, const int dest_port); static void wd_hb_recv(int sock, WdHbPacket * pkt, char *from_addr); /* create socket for sending heartbeat */ static int -wd_create_hb_send_socket(WdHbIf *hb_if) +wd_create_hb_send_socket(WdHbIf * hb_if) { - int sock; - int tos; + int sock; + int tos; /* create socket */ if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { /* socket create failed */ ereport(ERROR, - (errmsg("failed to create watchdog heartbeat sender socket"), + (errmsg("failed to create watchdog heartbeat sender socket"), errdetail("create socket failed with reason: \"%s\"", strerror(errno)))); } /* set socket option */ tos = IPTOS_LOWDELAY; - if (setsockopt(sock, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) == -1 ) + if (setsockopt(sock, IPPROTO_IP, IP_TOS, (char *) &tos, sizeof(tos)) == -1) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat sender socket"), + (errmsg("failed to create watchdog heartbeat sender socket"), errdetail("setsockopt(IP_TOS) failed with reason: \"%s\"", strerror(errno)))); } @@ -111,38 +112,39 @@ wd_create_hb_send_socket(WdHbIf *hb_if) if (geteuid() == 0) /* check root privileges */ { struct ifreq i; + strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name)); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat sender socket"), + (errmsg("failed to create watchdog heartbeat sender socket"), errdetail("setsockopt(SO_BINDTODEVICE) failed with reason: \"%s\"", strerror(errno)))); } ereport(LOG, - (errmsg("creating socket for sending heartbeat"), + (errmsg("creating socket for sending heartbeat"), errdetail("bind send socket to device: %s", i.ifr_name))); } else ereport(LOG, - (errmsg("creating socket for sending heartbeat"), + (errmsg("creating socket for sending heartbeat"), errdetail("setsockopt(SO_BINDTODEVICE) requires root privilege"))); } #else ereport(LOG, - (errmsg("creating socket for sending heartbeat"), + (errmsg("creating socket for sending heartbeat"), errdetail("setsockopt(SO_BINDTODEVICE) is not available on this platform"))); #endif } wd_set_reuseport(sock); ereport(LOG, - (errmsg("creating socket for sending heartbeat"), + (errmsg("creating socket for sending heartbeat"), errdetail("set SO_REUSEPORT"))); - if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) + if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) { close(sock); ereport(ERROR, @@ -155,13 +157,13 @@ wd_create_hb_send_socket(WdHbIf *hb_if) /* create socket for receiving heartbeat */ static int -wd_create_hb_recv_socket(WdHbIf *hb_if) +wd_create_hb_recv_socket(WdHbIf * hb_if) { struct sockaddr_in addr; - int sock; - const int one = 1; - int bind_tries; - int bind_is_done; + int sock; + const int one = 1; + int bind_tries; + int bind_is_done; memset(&(addr), 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -173,15 +175,15 @@ wd_create_hb_recv_socket(WdHbIf *hb_if) { /* socket create failed */ ereport(ERROR, - (errmsg("failed to create watchdog heartbeat receive socket"), + (errmsg("failed to create watchdog heartbeat receive socket"), errdetail("create socket failed with reason: \"%s\"", strerror(errno)))); } - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1 ) + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) == -1) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat receive socket"), + (errmsg("failed to create watchdog heartbeat receive socket"), errdetail("setsockopt(SO_REUSEADDR) failed with reason: \"%s\"", strerror(errno)))); } @@ -192,28 +194,29 @@ wd_create_hb_recv_socket(WdHbIf *hb_if) if (geteuid() == 0) /* check root privileges */ { struct ifreq i; + strlcpy(i.ifr_name, hb_if->if_name, sizeof(i.ifr_name)); if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &i, sizeof(i)) == -1) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat receive socket"), + (errmsg("failed to create watchdog heartbeat receive socket"), errdetail("setsockopt(SO_BINDTODEVICE) failed with reason: \"%s\"", strerror(errno)))); } ereport(LOG, - (errmsg("createing watchdog heartbeat receive socket."), + (errmsg("createing watchdog heartbeat receive socket."), errdetail("bind receive socket to device: \"%s\"", i.ifr_name))); } else ereport(LOG, - (errmsg("failed to create watchdog heartbeat receive socket."), + (errmsg("failed to create watchdog heartbeat receive socket."), errdetail("setsockopt(SO_BINDTODEVICE) requies root privilege"))); } #else ereport(LOG, - (errmsg("failed to create watchdog heartbeat receive socket"), + (errmsg("failed to create watchdog heartbeat receive socket"), errdetail("setsockopt(SO_BINDTODEVICE) is not available on this platform"))); #endif } @@ -221,18 +224,18 @@ wd_create_hb_recv_socket(WdHbIf *hb_if) wd_set_reuseport(sock); ereport(LOG, - (errmsg("creating watchdog heartbeat receive socket."), + (errmsg("creating watchdog heartbeat receive socket."), errdetail("set SO_REUSEPORT"))); bind_is_done = 0; for (bind_tries = 0; !bind_is_done && bind_tries < MAX_BIND_TRIES; bind_tries++) { - if (bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr)) < 0) + if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr)) < 0) { ereport(LOG, - (errmsg("failed to create watchdog heartbeat receive socket. retrying..."), - errdetail("bind failed with reason: \"%s\"", - strerror(errno)))); + (errmsg("failed to create watchdog heartbeat receive socket. retrying..."), + errdetail("bind failed with reason: \"%s\"", + strerror(errno)))); sleep(1); } @@ -247,15 +250,15 @@ wd_create_hb_recv_socket(WdHbIf *hb_if) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat receive socket"), + (errmsg("failed to create watchdog heartbeat receive socket"), errdetail("bind socket failed with reason: \"%s\"", strerror(errno)))); } - if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) + if (fcntl(sock, F_SETFD, FD_CLOEXEC) < 0) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat receive socket"), + (errmsg("failed to create watchdog heartbeat receive socket"), errdetail("setting close-on-exec flag failed with reason: \"%s\"", strerror(errno)))); } @@ -264,22 +267,22 @@ wd_create_hb_recv_socket(WdHbIf *hb_if) /* send heartbeat signal */ static void -wd_hb_send(int sock, WdHbPacket * pkt, int len, const char * host, const int port) +wd_hb_send(int sock, WdHbPacket * pkt, int len, const char *host, const int port) { - int rtn; + int rtn; struct sockaddr_in addr; struct hostent *hp; - WdHbPacket buf; + WdHbPacket buf; if (!host || !strlen(host)) ereport(ERROR, - (errmsg("failed to send watchdog heartbeat. host name is empty"))); + (errmsg("failed to send watchdog heartbeat. host name is empty"))); hp = gethostbyname(host); if ((hp == NULL) || (hp->h_addrtype != AF_INET)) ereport(ERROR, - (errmsg("failed to send watchdog heartbeat, gethostbyname() failed"), - errdetail("gethostbyname on \"%s\" failed with reason: \"%s\"",host, hstrerror(h_errno)))); + (errmsg("failed to send watchdog heartbeat, gethostbyname() failed"), + errdetail("gethostbyname on \"%s\" failed with reason: \"%s\"", host, hstrerror(h_errno)))); memmove((char *) &(addr.sin_addr), (char *) hp->h_addr, hp->h_length); @@ -289,11 +292,11 @@ wd_hb_send(int sock, WdHbPacket * pkt, int len, const char * host, const int por hton_wd_hb_packet(&buf, pkt); if ((rtn = sendto(sock, &buf, sizeof(WdHbPacket), 0, - (struct sockaddr *)&addr, sizeof(addr))) != len) + (struct sockaddr *) &addr, sizeof(addr))) != len) { ereport(ERROR, - (errmsg("failed to send watchdog heartbeat, sendto failed"), - errdetail("sending packet to \"%s\" failed with reason: \"%s\"",host, strerror(errno)))); + (errmsg("failed to send watchdog heartbeat, sendto failed"), + errdetail("sending packet to \"%s\" failed with reason: \"%s\"", host, strerror(errno)))); } ereport(DEBUG2, @@ -306,20 +309,21 @@ wd_hb_send(int sock, WdHbPacket * pkt, int len, const char * host, const int por * the function expects the from_addr to be at least WD_MAX_HOST_NAMELEN bytes long */ void -static wd_hb_recv(int sock, WdHbPacket * pkt, char *from_addr) +static +wd_hb_recv(int sock, WdHbPacket * pkt, char *from_addr) { - int rtn; + int rtn; struct sockaddr_in senderinfo; - socklen_t addrlen; - WdHbPacket buf; + socklen_t addrlen; + WdHbPacket buf; addrlen = sizeof(senderinfo); rtn = recvfrom(sock, &buf, sizeof(WdHbPacket), 0, - (struct sockaddr *)&senderinfo, &addrlen); + (struct sockaddr *) &senderinfo, &addrlen); if (rtn < 0) ereport(ERROR, - (errmsg("failed to receive heartbeat packet"))); + (errmsg("failed to receive heartbeat packet"))); else if (rtn == 0) ereport(ERROR, (errmsg("failed to receive heartbeat received zero length packet"))); @@ -327,24 +331,24 @@ static wd_hb_recv(int sock, WdHbPacket * pkt, char *from_addr) ereport(DEBUG2, (errmsg("watchdog heartbeat: received %d byte packet", rtn))); - strncpy(from_addr,inet_ntoa(senderinfo.sin_addr),WD_MAX_HOST_NAMELEN-1); + strncpy(from_addr, inet_ntoa(senderinfo.sin_addr), WD_MAX_HOST_NAMELEN - 1); ntoh_wd_hb_packet(pkt, &buf); } /* fork heartbeat receiver child */ pid_t -wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) +wd_hb_receiver(int fork_wait_time, WdHbIf * hb_if) { - int sock; - pid_t pid = 0; - WdHbPacket pkt; + int sock; + pid_t pid = 0; + WdHbPacket pkt; struct timeval tv; - char from[WD_MAX_HOST_NAMELEN]; - int from_pgpool_port; - char buf[WD_AUTH_HASH_LEN + 1]; - char pack_str[WD_MAX_PACKET_STRING]; - int pack_str_len; + char from[WD_MAX_HOST_NAMELEN]; + int from_pgpool_port; + char buf[WD_AUTH_HASH_LEN + 1]; + char pack_str[WD_MAX_PACKET_STRING]; + int pack_str_len; sigjmp_buf local_sigjmp_buf; pid = fork(); @@ -383,7 +387,7 @@ wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); - + MemoryContextSwitchTo(TopMemoryContext); sock = wd_create_hb_recv_socket(hb_if); @@ -394,24 +398,25 @@ wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) { /* Since not using PG_TRY, must reset error stack by hand */ error_context_stack = NULL; - + EmitErrorReport(); MemoryContextSwitchTo(TopMemoryContext); FlushErrorState(); } - + /* We can now handle ereport(ERROR) */ PG_exception_stack = &local_sigjmp_buf; - for(;;) + for (;;) { - int i; + int i; + MemoryContextSwitchTo(ProcessLoopContext); MemoryContextResetAndDeleteChildren(ProcessLoopContext); /* receive heartbeat signal */ wd_hb_recv(sock, &pkt, from); - /* authentication */ + /* authentication */ if (strlen(pool_config->wd_authkey)) { /* calculate hash from packet */ @@ -420,11 +425,11 @@ wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) if (buf[0] == '\0') ereport(WARNING, - (errmsg("failed to calculate wd_authkey hash from a received heartbeat packet"))); + (errmsg("failed to calculate wd_authkey hash from a received heartbeat packet"))); if (strcmp(pkt.hash, buf)) ereport(ERROR, - (errmsg("watchdog heartbeat receive"), + (errmsg("watchdog heartbeat receive"), errdetail("authentication failed"))); } @@ -433,15 +438,15 @@ wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) /* who send this packet? */ from_pgpool_port = pkt.from_pgpool_port; - for (i = 0; i< gslifeCheckCluster->nodeCount; i++) + for (i = 0; i < gslifeCheckCluster->nodeCount; i++) { - LifeCheckNode* node = &gslifeCheckCluster->lifeCheckNodes[i]; + LifeCheckNode *node = &gslifeCheckCluster->lifeCheckNodes[i]; ereport(DEBUG2, (errmsg("received heartbeat signal from \"%s:%d\" hostname:%s", from, from_pgpool_port, pkt.from))); - if ( (!strcmp(node->hostName, pkt.from) || !strcmp(node->hostName, from)) && node->pgpoolPort == from_pgpool_port) + if ((!strcmp(node->hostName, pkt.from) || !strcmp(node->hostName, from)) && node->pgpoolPort == from_pgpool_port) { /* this is the first packet or the latest packet */ if (!WD_TIME_ISSET(node->hb_send_time) || @@ -449,8 +454,8 @@ wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) { ereport(DEBUG1, (errmsg("received heartbeat signal from \"%s(%s):%d\" node:%s", - from,pkt.from, from_pgpool_port, node->nodeName))); - + from, pkt.from, from_pgpool_port, node->nodeName))); + node->hb_send_time = pkt.send_time; node->hb_last_recv_time = tv; } @@ -469,14 +474,14 @@ wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if) /* fork heartbeat sender child */ pid_t -wd_hb_sender(int fork_wait_time, WdHbIf *hb_if) +wd_hb_sender(int fork_wait_time, WdHbIf * hb_if) { - int sock; - pid_t pid = 0; - WdHbPacket pkt; + int sock; + pid_t pid = 0; + WdHbPacket pkt; - char pack_str[WD_MAX_PACKET_STRING]; - int pack_str_len; + char pack_str[WD_MAX_PACKET_STRING]; + int pack_str_len; sigjmp_buf local_sigjmp_buf; pid = fork(); @@ -515,7 +520,7 @@ wd_hb_sender(int fork_wait_time, WdHbIf *hb_if) ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); - + MemoryContextSwitchTo(TopMemoryContext); sock = wd_create_hb_send_socket(hb_if); @@ -526,17 +531,17 @@ wd_hb_sender(int fork_wait_time, WdHbIf *hb_if) { /* Since not using PG_TRY, must reset error stack by hand */ error_context_stack = NULL; - + EmitErrorReport(); MemoryContextSwitchTo(TopMemoryContext); FlushErrorState(); sleep(pool_config->wd_heartbeat_keepalive); } - + /* We can now handle ereport(ERROR) */ PG_exception_stack = &local_sigjmp_buf; - for(;;) + for (;;) { MemoryContextSwitchTo(ProcessLoopContext); MemoryContextResetAndDeleteChildren(ProcessLoopContext); @@ -555,7 +560,7 @@ wd_hb_sender(int fork_wait_time, WdHbIf *hb_if) if (pkt.hash[0] == '\0') ereport(WARNING, - (errmsg("failed to calculate wd_authkey hash from a heartbeat packet to be sent"))); + (errmsg("failed to calculate wd_authkey hash from a heartbeat packet to be sent"))); } /* send heartbeat signal */ @@ -573,17 +578,17 @@ hb_sender_exit(int sig) { switch (sig) { - case SIGTERM: /* smart shutdown */ - case SIGINT: /* fast shutdown */ - case SIGQUIT: /* immediate shutdown */ + case SIGTERM: /* smart shutdown */ + case SIGINT: /* fast shutdown */ + case SIGQUIT: /* immediate shutdown */ ereport(DEBUG1, - (errmsg("watchdog heartbeat sender child receives shutdown request signal %d", sig ))); + (errmsg("watchdog heartbeat sender child receives shutdown request signal %d", sig))); break; default: ereport(LOG, - (errmsg("hb_sender child receives unknown signal: %d", sig ))); + (errmsg("hb_sender child receives unknown signal: %d", sig))); } - + exit(0); } @@ -592,17 +597,17 @@ hb_receiver_exit(int sig) { switch (sig) { - case SIGTERM: /* smart shutdown */ - case SIGINT: /* fast shutdown */ - case SIGQUIT: /* immediate shutdown */ + case SIGTERM: /* smart shutdown */ + case SIGINT: /* fast shutdown */ + case SIGQUIT: /* immediate shutdown */ ereport(DEBUG1, - (errmsg("watchdog heartbeat receiver child receives shutdown request signal %d", sig ))); + (errmsg("watchdog heartbeat receiver child receives shutdown request signal %d", sig))); break; default: ereport(LOG, - (errmsg("hb_receiver child receives unknown signal: %d", sig ))); + (errmsg("hb_receiver child receives unknown signal: %d", sig))); } - + exit(0); } @@ -642,11 +647,12 @@ ntoh_wd_hb_packet(WdHbPacket * to, WdHbPacket * from) /* convert packet to string and return length of the string */ static int -packet_to_string_hb(WdHbPacket *pkt, char *str, int maxlen) +packet_to_string_hb(WdHbPacket * pkt, char *str, int maxlen) { - int len; + int len; + len = snprintf(str, maxlen, "tv_sec=%ld tv_usec=%ld from=%s", - pkt->send_time.tv_sec, pkt->send_time.tv_usec, pkt->from); + pkt->send_time.tv_sec, pkt->send_time.tv_usec, pkt->from); return len; } @@ -656,17 +662,18 @@ packet_to_string_hb(WdHbPacket *pkt, char *str, int maxlen) * in the compile time but not available in the run time, just emit a * log and treat it as normal. */ -static void wd_set_reuseport(int sock) +static void +wd_set_reuseport(int sock) { #if defined(SO_REUSEPORT) - int one = 1; + int one = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) { if (errno == EINVAL || errno == ENOPROTOOPT) { ereport(LOG, - (errmsg("error seting SO_REUSEPORT option to the socket"), + (errmsg("error seting SO_REUSEPORT option to the socket"), errdetail("setsockopt(SO_REUSEPORT) is not supported by the kernel. detail: %s", strerror(errno)))); } @@ -674,7 +681,7 @@ static void wd_set_reuseport(int sock) { close(sock); ereport(ERROR, - (errmsg("failed to create watchdog heartbeat socket"), + (errmsg("failed to create watchdog heartbeat socket"), errdetail("setsockopt(SO_REUSEPORT) failed with reason: \"%s\"", strerror(errno)))); } } diff --git a/src/watchdog/wd_if.c b/src/watchdog/wd_if.c index e92f4a377..a7ea3d240 100644 --- a/src/watchdog/wd_if.c +++ b/src/watchdog/wd_if.c @@ -3,7 +3,7 @@ * * Handles watchdog connection, and protocol communication with pgpool-II * - * pgpool: a language independent connection pool server for PostgreSQL + * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * * Copyright (c) 2003-2016 PgPool Global Development Group @@ -38,14 +38,14 @@ #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <linux/if.h> -#else /* __linux__ */ +#else /* __linux__ */ #include <net/route.h> #include <net/if.h> #ifdef AF_LINK #include <net/if_dl.h> #endif -#endif /* __linux__ */ +#endif /* __linux__ */ #include <arpa/inet.h> #include <ifaddrs.h> @@ -64,35 +64,37 @@ #define IFF_LOWER_UP 0x10000 #endif -static int exec_if_cmd(char * path,char * command); +static int exec_if_cmd(char *path, char *command); -List* get_all_local_ips(void) +List * +get_all_local_ips(void) { - struct ifaddrs *ifAddrStruct=NULL; - struct ifaddrs *ifa=NULL; - void *tmpAddrPtr=NULL; - List *local_addresses = NULL; - + struct ifaddrs *ifAddrStruct = NULL; + struct ifaddrs *ifa = NULL; + void *tmpAddrPtr = NULL; + List *local_addresses = NULL; + getifaddrs(&ifAddrStruct); for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) continue; - + if (ifa->ifa_addr->sa_family == AF_INET) { - char *addressBuffer; + char *addressBuffer; + if (!strncasecmp("lo", ifa->ifa_name, 2)) - continue; /* We do not need loop back addresses */ + continue; /* We do not need loop back addresses */ - tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr; addressBuffer = palloc(INET_ADDRSTRLEN); inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); - local_addresses = lappend(local_addresses,addressBuffer); + local_addresses = lappend(local_addresses, addressBuffer); } } - if (ifAddrStruct!=NULL) + if (ifAddrStruct != NULL) freeifaddrs(ifAddrStruct); return local_addresses; } @@ -101,30 +103,30 @@ List* get_all_local_ips(void) int wd_IP_up(void) { - int rtn = WD_OK; - char path[WD_MAX_PATH_LEN]; - char* command; - int i; + int rtn = WD_OK; + char path[WD_MAX_PATH_LEN]; + char *command; + int i; if (strlen(pool_config->delegate_IP) == 0) { ereport(LOG, - (errmsg("trying to acquire the delegate IP address, but delegate IP is not configured"))); + (errmsg("trying to acquire the delegate IP address, but delegate IP is not configured"))); return WD_OK; } command = wd_get_cmd(pool_config->if_up_cmd); if (command) { - snprintf(path,sizeof(path),"%s/%s",pool_config->if_cmd_path,command); - rtn = exec_if_cmd(path,pool_config->if_up_cmd); + snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); + rtn = exec_if_cmd(path, pool_config->if_up_cmd); pfree(command); } else { ereport(LOG, - (errmsg("failed to acquire the delegate IP address"), - errdetail("unable to parse the if_up_cmd:\"%s\"",pool_config->if_up_cmd))); + (errmsg("failed to acquire the delegate IP address"), + errdetail("unable to parse the if_up_cmd:\"%s\"", pool_config->if_up_cmd))); return WD_NG; } @@ -133,16 +135,16 @@ wd_IP_up(void) command = wd_get_cmd(pool_config->arping_cmd); if (command) { - snprintf(path,sizeof(path),"%s/%s",pool_config->arping_path,command); - rtn = exec_if_cmd(path,pool_config->arping_cmd); + snprintf(path, sizeof(path), "%s/%s", pool_config->arping_path, command); + rtn = exec_if_cmd(path, pool_config->arping_cmd); pfree(command); } else { rtn = WD_NG; ereport(LOG, - (errmsg("failed to acquire the delegate IP address"), - errdetail("unable to parse the arping_cmd:\"%s\"",pool_config->arping_cmd))); + (errmsg("failed to acquire the delegate IP address"), + errdetail("unable to parse the arping_cmd:\"%s\"", pool_config->arping_cmd))); } } @@ -153,8 +155,8 @@ wd_IP_up(void) if (wd_is_ip_exists(pool_config->delegate_IP) == true) break; ereport(LOG, - (errmsg("waiting for the delegate IP address to become active"), - errdetail("waiting... count: %d", i+1))); + (errmsg("waiting for the delegate IP address to become active"), + errdetail("waiting... count: %d", i + 1))); } if (i >= WD_TRY_PING_AT_IPUP) @@ -163,11 +165,11 @@ wd_IP_up(void) if (rtn == WD_OK) ereport(LOG, - (errmsg("successfully acquired the delegate IP:\"%s\"",pool_config->delegate_IP), + (errmsg("successfully acquired the delegate IP:\"%s\"", pool_config->delegate_IP), errdetail("'if_up_cmd' returned with success"))); else ereport(LOG, - (errmsg("failed to acquire the delegate IP address"), + (errmsg("failed to acquire the delegate IP address"), errdetail("'if_up_cmd' failed"))); return rtn; } @@ -175,14 +177,14 @@ wd_IP_up(void) int wd_IP_down(void) { - int rtn = WD_OK; - char path[WD_MAX_PATH_LEN]; - char* command; + int rtn = WD_OK; + char path[WD_MAX_PATH_LEN]; + char *command; if (strlen(pool_config->delegate_IP) == 0) { ereport(LOG, - (errmsg("trying to release the delegate IP address, but delegate IP is not configured"))); + (errmsg("trying to release the delegate IP address, but delegate IP is not configured"))); return WD_OK; } @@ -190,42 +192,43 @@ wd_IP_down(void) if (command) { snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); - rtn = exec_if_cmd(path,pool_config->if_down_cmd); + rtn = exec_if_cmd(path, pool_config->if_down_cmd); pfree(command); } else { ereport(LOG, - (errmsg("failed to release the delegate IP address"), - errdetail("unable to parse the if_down_cmd:\"%s\"",pool_config->if_down_cmd))); + (errmsg("failed to release the delegate IP address"), + errdetail("unable to parse the if_down_cmd:\"%s\"", pool_config->if_down_cmd))); return WD_NG; } if (rtn == WD_OK) { ereport(LOG, - (errmsg("successfully released the delegate IP:\"%s\"",pool_config->delegate_IP), + (errmsg("successfully released the delegate IP:\"%s\"", pool_config->delegate_IP), errdetail("'if_down_cmd' returned with success"))); } else { ereport(LOG, - (errmsg("failed to release the delegate IP:\"%s\"",pool_config->delegate_IP), + (errmsg("failed to release the delegate IP:\"%s\"", pool_config->delegate_IP), errdetail("'if_down_cmd' failed"))); } return rtn; } -char* -wd_get_cmd(char* cmd) +char * +wd_get_cmd(char *cmd) { - char *command = NULL; + char *command = NULL; if (cmd && *cmd) { - char* tmp_str = pstrdup(cmd); - char* token = strtok(tmp_str," "); + char *tmp_str = pstrdup(cmd); + char *token = strtok(tmp_str, " "); + if (token) command = pstrdup(token); pfree(tmp_str); @@ -234,32 +237,34 @@ wd_get_cmd(char* cmd) } static int -exec_if_cmd(char * path,char * command) +exec_if_cmd(char *path, char *command) { - int pfd[2]; - int status; - char * args[24]; - int pid, i = 0; - char* buf; - char *bp, *ep; + int pfd[2]; + int status; + char *args[24]; + int pid, + i = 0; + char *buf; + char *bp, + *ep; if (pipe(pfd) == -1) { ereport(WARNING, - (errmsg("while executing interface up/down command, pipe open failed with error \"%s\"",strerror(errno)))); + (errmsg("while executing interface up/down command, pipe open failed with error \"%s\"", strerror(errno)))); return WD_NG; } - buf = string_replace(command,"$_IP_$",pool_config->delegate_IP); + buf = string_replace(command, "$_IP_$", pool_config->delegate_IP); bp = buf; while (*bp == ' ') { - bp ++; + bp++; } while (*bp != '\0') { - ep = strchr(bp,' '); + ep = strchr(bp, ' '); if (ep != NULL) { *ep = '\0'; @@ -267,10 +272,10 @@ exec_if_cmd(char * path,char * command) args[i++] = bp; if (ep != NULL) { - bp = ep +1; + bp = ep + 1; while (*bp == ' ') { - bp ++; + bp++; } } else @@ -284,7 +289,7 @@ exec_if_cmd(char * path,char * command) if (pid == -1) { ereport(FATAL, - (errmsg("failed to execute interface up/down command"), + (errmsg("failed to execute interface up/down command"), errdetail("fork() failed with reason: \"%s\"", strerror(errno)))); } if (pid == 0) @@ -294,7 +299,7 @@ exec_if_cmd(char * path,char * command) close(STDOUT_FILENO); dup2(pfd[1], STDOUT_FILENO); close(pfd[0]); - status = execv(path,args); + status = execv(path, args); exit(0); } else @@ -303,7 +308,8 @@ exec_if_cmd(char * path,char * command) close(pfd[1]); for (;;) { - int result; + int result; + result = waitpid(pid, &status, 0); if (result < 0) { @@ -311,7 +317,7 @@ exec_if_cmd(char * path,char * command) continue; ereport(DEBUG1, - (errmsg("watchdog exec waitpid()failed"), + (errmsg("watchdog exec waitpid()failed"), errdetail("waitpid() system call failed with reason \"%s\"", strerror(errno)))); return WD_NG; @@ -320,8 +326,8 @@ exec_if_cmd(char * path,char * command) if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) { ereport(DEBUG1, - (errmsg("watchdog exec interface up/down command failed"), - errdetail("'%s' failed. exit status: %d",command, WEXITSTATUS(status)))); + (errmsg("watchdog exec interface up/down command failed"), + errdetail("'%s' failed. exit status: %d", command, WEXITSTATUS(status)))); return WD_NG; } @@ -331,50 +337,52 @@ exec_if_cmd(char * path,char * command) close(pfd[0]); } ereport(DEBUG1, - (errmsg("watchdog exec interface up/down command: '%s' succeeded", command))); + (errmsg("watchdog exec interface up/down command: '%s' succeeded", command))); return WD_OK; } -int create_monitoring_socket(void) +int +create_monitoring_socket(void) { - int sock = -1; + int sock = -1; #ifdef __linux__ sock = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE); - + #else sock = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC); #endif if (sock < 0) ereport(ERROR, (errmsg("watchdog: VIP monitoring failed to create socket"), - errdetail("socket() failed with error \"%s\"",strerror(errno)))); - + errdetail("socket() failed with error \"%s\"", strerror(errno)))); + #ifdef __linux__ struct sockaddr_nl addr; - + memset(&addr, 0x00, sizeof(addr)); addr.nl_family = AF_NETLINK; addr.nl_groups = RTMGRP_IPV4_IFADDR | RTMGRP_LINK; - - if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) < 0) + + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { close(sock); ereport(ERROR, (errmsg("watchdog: VIP monitoring failed to bind socket"), - errdetail("bind() failed with error \"%s\"",strerror(errno)))); + errdetail("bind() failed with error \"%s\"", strerror(errno)))); } #endif - + return sock; } #ifdef __linux__ -bool read_interface_change_event(int sock, bool* link_event, bool* deleted) +bool +read_interface_change_event(int sock, bool *link_event, bool *deleted) { - char buffer[4096]; - int len; + char buffer[4096]; + int len; struct iovec iov; struct msghdr hdr; struct nlmsghdr *nlhdr; @@ -382,36 +390,36 @@ bool read_interface_change_event(int sock, bool* link_event, bool* deleted) *deleted = false; *link_event = false; - + iov.iov_base = buffer; iov.iov_len = sizeof(buffer); - + memset(&hdr, 0, sizeof(hdr)); hdr.msg_iov = &iov; hdr.msg_iovlen = 1; - + len = recvmsg(sock, &hdr, 0); if (len < 0) { ereport(DEBUG1, (errmsg("VIP monitoring failed to receive from socket"), - errdetail("recvmsg() failed with error \"%s\"",strerror(errno)))); + errdetail("recvmsg() failed with error \"%s\"", strerror(errno)))); return false; } - - nlhdr = (struct nlmsghdr *)buffer; - for (; NLMSG_OK(nlhdr, len) ;nlhdr = NLMSG_NEXT(nlhdr, len)) + nlhdr = (struct nlmsghdr *) buffer; + + for (; NLMSG_OK(nlhdr, len); nlhdr = NLMSG_NEXT(nlhdr, len)) { - if(nlhdr->nlmsg_type == NLMSG_DONE) + if (nlhdr->nlmsg_type == NLMSG_DONE) break; ifimsg = NLMSG_DATA(nlhdr); - switch(nlhdr->nlmsg_type) + switch (nlhdr->nlmsg_type) { case RTM_DELLINK: - *deleted = true; /* fallthrough */ + *deleted = true; /* fallthrough */ case RTM_NEWLINK: if (!(ifimsg->ifi_flags & IFF_LOWER_UP) || !(ifimsg->ifi_flags & IFF_RUNNING)) *deleted = true; @@ -421,7 +429,7 @@ bool read_interface_change_event(int sock, bool* link_event, bool* deleted) break; case RTM_DELADDR: - *deleted = true; /* fallthrough */ + *deleted = true; /* fallthrough */ case RTM_NEWADDR: *link_event = false; return true; @@ -434,7 +442,7 @@ bool read_interface_change_event(int sock, bool* link_event, bool* deleted) return false; } -#else /* For non linux chaps */ +#else /* For non linux chaps */ #if defined(__OpenBSD__) || defined(__FreeBSD__) #define SALIGN (sizeof(long) - 1) #else @@ -444,12 +452,13 @@ bool read_interface_change_event(int sock, bool* link_event, bool* deleted) #define SA_RLEN(sa) ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1)) /* With the help from https://github.com/miniupnp/miniupnp/blob/master/minissdpd/ifacewatch.c */ -bool read_interface_change_event(int sock, bool* link_event, bool* deleted) +bool +read_interface_change_event(int sock, bool *link_event, bool *deleted) { - char buffer[1024]; - int len; + char buffer[1024]; + int len; struct rt_msghdr *nlhdr; - + *deleted = false; *link_event = false; @@ -458,22 +467,22 @@ bool read_interface_change_event(int sock, bool* link_event, bool* deleted) { ereport(DEBUG1, (errmsg("VIP monitoring failed to receive from socket"), - errdetail("recv() failed with error \"%s\"",strerror(errno)))); + errdetail("recv() failed with error \"%s\"", strerror(errno)))); return false; } - - nlhdr = (struct rt_msghdr *)buffer; - switch(nlhdr->rtm_type) + + nlhdr = (struct rt_msghdr *) buffer; + switch (nlhdr->rtm_type) { case RTM_DELETE: - *deleted = true; /* fallthrough */ + *deleted = true; /* fallthrough */ case RTM_ADD: *link_event = true; return true; break; case RTM_DELADDR: - *deleted = true; /* fallthrough */ + *deleted = true; /* fallthrough */ case RTM_NEWADDR: *link_event = false; return true; @@ -486,28 +495,29 @@ bool read_interface_change_event(int sock, bool* link_event, bool* deleted) } #endif -bool is_interface_up(struct ifaddrs *ifa) +bool +is_interface_up(struct ifaddrs *ifa) { - bool result = false; + bool result = false; if (ifa->ifa_flags & IFF_RUNNING) { ereport(DEBUG1, - (errmsg("network interface \"%s\" link is active",ifa->ifa_name))); + (errmsg("network interface \"%s\" link is active", ifa->ifa_name))); if (ifa->ifa_flags & IFF_LOWER_UP) { ereport(DEBUG1, - (errmsg("network interface \"%s\" link is up",ifa->ifa_name))); + (errmsg("network interface \"%s\" link is up", ifa->ifa_name))); result = true; } else ereport(NOTICE, - (errmsg("network interface \"%s\" link is down",ifa->ifa_name))); + (errmsg("network interface \"%s\" link is down", ifa->ifa_name))); } else ereport(NOTICE, - (errmsg("network interface \"%s\" link is inactive",ifa->ifa_name))); + (errmsg("network interface \"%s\" link is inactive", ifa->ifa_name))); return result; } diff --git a/src/watchdog/wd_json_data.c b/src/watchdog/wd_json_data.c index 328191d7d..f14c52e72 100644 --- a/src/watchdog/wd_json_data.c +++ b/src/watchdog/wd_json_data.c @@ -33,15 +33,17 @@ #include "pool.h" -POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len) +POOL_CONFIG * +get_pool_config_from_json(char *json_data, int data_len) { - int i; + int i; json_value *root = NULL; json_value *value = NULL; POOL_CONFIG *config = palloc0(sizeof(POOL_CONFIG)); + config->backend_desc = palloc0(sizeof(BackendDesc)); - root = json_parse(json_data,data_len); + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) goto ERROR_EXIT; @@ -64,7 +66,7 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len) goto ERROR_EXIT; 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", (int*)&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_bool_value_for_key(root, "replication_stop_on_mismatch", &config->replication_stop_on_mismatch)) goto ERROR_EXIT; @@ -74,7 +76,7 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len) goto ERROR_EXIT; 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", (int*)&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_bool_value_for_key(root, "connection_cache", &config->connection_cache)) goto ERROR_EXIT; @@ -106,7 +108,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, "wd_priority", &config->wd_priority)) goto ERROR_EXIT; - if (json_get_int_value_for_key(root, "master_slave_sub_mode", (int*)&config->master_slave_sub_mode)) + if (json_get_int_value_for_key(root, "master_slave_sub_mode", (int *) &config->master_slave_sub_mode)) goto ERROR_EXIT; if (json_get_bool_value_for_key(root, "failover_when_quorum_exists", &config->failover_when_quorum_exists)) @@ -117,7 +119,7 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len) goto ERROR_EXIT; /* backend_desc array */ - value = json_get_value_for_key(root,"backend_desc"); + value = json_get_value_for_key(root, "backend_desc"); if (value == NULL || value->type != json_array) goto ERROR_EXIT; @@ -125,25 +127,27 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len) for (i = 0; i < config->backend_desc->num_backends; i++) { json_value *arr_value = value->u.array.values[i]; - char *ptr; + char *ptr; + if (json_get_int_value_for_key(arr_value, "backend_port", &config->backend_desc->backend_info[i].backend_port)) goto ERROR_EXIT; ptr = json_get_string_value_for_key(arr_value, "backend_hostname"); if (ptr == NULL) goto ERROR_EXIT; - strncpy(config->backend_desc->backend_info[i].backend_hostname, ptr,sizeof(config->backend_desc->backend_info[i].backend_hostname) -1); + strncpy(config->backend_desc->backend_info[i].backend_hostname, ptr, sizeof(config->backend_desc->backend_info[i].backend_hostname) - 1); } /* wd_remote_nodes array */ - value = json_get_value_for_key(root,"wd_remote_nodes"); + value = json_get_value_for_key(root, "wd_remote_nodes"); if (value == NULL || value->type != json_array) goto ERROR_EXIT; - + config->wd_remote_nodes.num_wd = value->u.array.length; for (i = 0; i < config->wd_remote_nodes.num_wd; i++) { json_value *arr_value = value->u.array.values[i]; - char *ptr; + char *ptr; + if (json_get_int_value_for_key(arr_value, "wd_port", &config->wd_remote_nodes.wd_remote_node_info[i].wd_port)) goto ERROR_EXIT; if (json_get_int_value_for_key(arr_value, "pgpool_port", &config->wd_remote_nodes.wd_remote_node_info[i].pgpool_port)) @@ -151,7 +155,7 @@ POOL_CONFIG* get_pool_config_from_json(char* json_data, int data_len) ptr = json_get_string_value_for_key(arr_value, "hostname"); if (ptr == NULL) goto ERROR_EXIT; - strncpy(config->wd_remote_nodes.wd_remote_node_info[i].hostname, ptr,sizeof(config->wd_remote_nodes.wd_remote_node_info[i].hostname) -1); + strncpy(config->wd_remote_nodes.wd_remote_node_info[i].hostname, ptr, sizeof(config->wd_remote_nodes.wd_remote_node_info[i].hostname) - 1); } json_value_free(root); @@ -166,12 +170,13 @@ ERROR_EXIT: return NULL; } -char* get_pool_config_json(void) +char * +get_pool_config_json(void) { - int i; - char* json_str; + int i; + char *json_str; - JsonNode* jNode = jw_create_with_object(true); + JsonNode *jNode = jw_create_with_object(true); jw_put_int(jNode, "num_init_children", pool_config->num_init_children); jw_put_int(jNode, "listen_backlog_multiplier", pool_config->listen_backlog_multiplier); @@ -211,26 +216,26 @@ char* get_pool_config_json(void) /* Array of backends */ jw_start_array(jNode, "backend_desc"); - for (i=0; i < pool_config->backend_desc->num_backends; i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { jw_start_object(jNode, "BackendInfo"); - jw_put_string(jNode, "backend_hostname",pool_config->backend_desc->backend_info[i].backend_hostname); + jw_put_string(jNode, "backend_hostname", pool_config->backend_desc->backend_info[i].backend_hostname); jw_put_int(jNode, "backend_port", pool_config->backend_desc->backend_info[i].backend_port); jw_end_element(jNode); } - jw_end_element(jNode); /* backend_desc array End */ + jw_end_element(jNode); /* backend_desc array End */ /* Array of wd_remote_nodes */ jw_start_array(jNode, "wd_remote_nodes"); - for (i=0; i < pool_config->wd_remote_nodes.num_wd; i++) + for (i = 0; i < pool_config->wd_remote_nodes.num_wd; i++) { jw_start_object(jNode, "WdRemoteNodesConfig"); - jw_put_string(jNode, "hostname",pool_config->wd_remote_nodes.wd_remote_node_info[i].hostname); + jw_put_string(jNode, "hostname", pool_config->wd_remote_nodes.wd_remote_node_info[i].hostname); jw_put_int(jNode, "wd_port", pool_config->wd_remote_nodes.wd_remote_node_info[i].wd_port); jw_put_int(jNode, "pgpool_port", pool_config->wd_remote_nodes.wd_remote_node_info[i].pgpool_port); jw_end_element(jNode); } - jw_end_element(jNode); /* wd_remote_nodes array End */ + jw_end_element(jNode); /* wd_remote_nodes array End */ jw_finish_document(jNode); json_str = pstrdup(jw_get_json_string(jNode)); @@ -241,16 +246,17 @@ char* get_pool_config_json(void) /* The function returs the simple JSON string that contains * only one KEY,VALUE along with the authkey key value if provided */ -char* get_simple_request_json(char *key, char* value, unsigned int sharedKey, char* authKey) +char * +get_simple_request_json(char *key, char *value, unsigned int sharedKey, char *authKey) { - char* json_str; + char *json_str; - JsonNode* jNode = jw_create_with_object(true); + JsonNode *jNode = jw_create_with_object(true); - jw_put_int(jNode, WD_IPC_SHARED_KEY, sharedKey); /* put the shared key*/ + jw_put_int(jNode, WD_IPC_SHARED_KEY, sharedKey); /* put the shared key */ if (authKey != NULL && strlen(authKey) > 0) - jw_put_string(jNode, WD_IPC_AUTH_KEY, authKey); /* put the auth key*/ + jw_put_string(jNode, WD_IPC_AUTH_KEY, authKey); /* put the auth key */ jw_put_string(jNode, key, value); jw_finish_document(jNode); @@ -259,27 +265,29 @@ char* get_simple_request_json(char *key, char* value, unsigned int sharedKey, ch return json_str; } -char* get_data_request_json(char* request_type, unsigned int sharedKey, char* authKey) +char * +get_data_request_json(char *request_type, unsigned int sharedKey, char *authKey) { return get_simple_request_json(WD_JSON_KEY_DATA_REQ_TYPE, request_type, sharedKey, authKey); } -bool parse_data_request_json(char* json_data, int data_len, char** request_type) +bool +parse_data_request_json(char *json_data, int data_len, char **request_type) { json_value *root; - char* ptr; + char *ptr; *request_type = NULL; - root = json_parse(json_data,data_len); + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) { json_value_free(root); ereport(LOG, - (errmsg("watchdog is unable to parse data request json"), - errdetail("invalid json data \"%s\"",json_data))); + (errmsg("watchdog is unable to parse data request json"), + errdetail("invalid json data \"%s\"", json_data))); return false; } ptr = json_get_string_value_for_key(root, WD_JSON_KEY_DATA_REQ_TYPE); @@ -287,8 +295,8 @@ bool parse_data_request_json(char* json_data, int data_len, char** request_type) { json_value_free(root); ereport(LOG, - (errmsg("watchdog is unable to parse data request json"), - errdetail("request name node not found in json data \"%s\"",json_data))); + (errmsg("watchdog is unable to parse data request json"), + errdetail("request name node not found in json data \"%s\"", json_data))); return false; } *request_type = pstrdup(ptr); @@ -300,21 +308,24 @@ bool parse_data_request_json(char* json_data, int data_len, char** request_type) /* The function reads the backend node status from shared memory * and creates a json packet from it */ -char* get_backend_node_status_json(WatchdogNode* wdNode) +char * +get_backend_node_status_json(WatchdogNode * wdNode) { - int i; - char* json_str; - JsonNode* jNode = jw_create_with_object(true); + int i; + char *json_str; + JsonNode *jNode = jw_create_with_object(true); jw_start_array(jNode, "BackendNodeStatusList"); - for (i=0;i< pool_config->backend_desc->num_backends;i++) + for (i = 0; i < pool_config->backend_desc->num_backends; i++) { BACKEND_STATUS backend_status = pool_config->backend_desc->backend_info[i].backend_status; + if (backend_status == CON_DOWN && pool_config->backend_desc->backend_info[i].quarantine) { - /* since quarantine nodes are not cluster wide - * so send CON_WATI status for quarantine nodes + /* + * since quarantine nodes are not cluster wide so send CON_WATI + * status for quarantine nodes */ backend_status = CON_CONNECT_WAIT; } @@ -323,7 +334,7 @@ char* get_backend_node_status_json(WatchdogNode* wdNode) /* put the primary node id */ jw_end_element(jNode); jw_put_int(jNode, "PrimaryNodeId", Req_info->primary_node_id); - jw_put_string(jNode, "NodeName",wdNode->nodeName); + jw_put_string(jNode, "NodeName", wdNode->nodeName); jw_finish_document(jNode); json_str = pstrdup(jw_get_json_string(jNode)); @@ -331,25 +342,26 @@ char* get_backend_node_status_json(WatchdogNode* wdNode) return json_str; } -WDPGBackendStatus* get_pg_backend_node_status_from_json(char* json_data, int data_len) +WDPGBackendStatus * +get_pg_backend_node_status_from_json(char *json_data, int data_len) { json_value *root = NULL; json_value *value = NULL; - char *ptr; - int i; - WDPGBackendStatus* backendStatus = NULL; + char *ptr; + int i; + WDPGBackendStatus *backendStatus = NULL; - root = json_parse(json_data,data_len); + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) return NULL; /* backend status array */ - value = json_get_value_for_key(root,"BackendNodeStatusList"); + value = json_get_value_for_key(root, "BackendNodeStatusList"); if (value == NULL || value->type != json_array) return NULL; - if (value->u.array.length <=0 || value->u.array.length > MAX_NUM_BACKENDS ) + if (value->u.array.length <= 0 || value->u.array.length > MAX_NUM_BACKENDS) return NULL; backendStatus = palloc(sizeof(WDPGBackendStatus)); @@ -363,14 +375,14 @@ WDPGBackendStatus* get_pg_backend_node_status_from_json(char* json_data, int dat if (json_get_int_value_for_key(root, "PrimaryNodeId", &backendStatus->primary_node_id)) { ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find Watchdog Node ID"))); } ptr = json_get_string_value_for_key(root, "NodeName"); if (ptr) { - strncpy(backendStatus->nodeName, ptr, sizeof(backendStatus->nodeName) -1); + strncpy(backendStatus->nodeName, ptr, sizeof(backendStatus->nodeName) - 1); } else { @@ -380,26 +392,27 @@ WDPGBackendStatus* get_pg_backend_node_status_from_json(char* json_data, int dat return backendStatus; } -char* get_beacon_message_json(WatchdogNode* wdNode) +char * +get_beacon_message_json(WatchdogNode * wdNode) { - char* json_str; + char *json_str; struct timeval current_time; - long seconds_since_current_state; - long seconds_since_node_startup; + long seconds_since_current_state; + long seconds_since_node_startup; - gettimeofday(&current_time,NULL); + gettimeofday(&current_time, NULL); seconds_since_current_state = WD_TIME_DIFF_SEC(current_time, wdNode->current_state_time); seconds_since_node_startup = WD_TIME_DIFF_SEC(current_time, wdNode->startup_time); - JsonNode* jNode = jw_create_with_object(true); + JsonNode *jNode = jw_create_with_object(true); jw_put_int(jNode, "State", wdNode->state); jw_put_long(jNode, "SecondsSinceStartup", seconds_since_node_startup); jw_put_long(jNode, "SecondsSinceCurrentState", seconds_since_current_state); jw_put_int(jNode, "QuorumStatus", wdNode->quorum_status); jw_put_int(jNode, "AliveNodeCount", wdNode->standby_nodes_count); - jw_put_bool(jNode, "Escalated", wdNode->escalated == 0?false:true); + jw_put_bool(jNode, "Escalated", wdNode->escalated == 0 ? false : true); jw_finish_document(jNode); json_str = pstrdup(jw_get_json_string(jNode)); @@ -407,37 +420,38 @@ char* get_beacon_message_json(WatchdogNode* wdNode) return json_str; } -char* get_watchdog_node_info_json(WatchdogNode* wdNode, char* authkey) +char * +get_watchdog_node_info_json(WatchdogNode * wdNode, char *authkey) { - char* json_str; - long seconds_since_current_state; - long seconds_since_node_startup; + char *json_str; + long seconds_since_current_state; + long seconds_since_node_startup; struct timeval current_time; - gettimeofday(&current_time,NULL); + gettimeofday(&current_time, NULL); seconds_since_current_state = WD_TIME_DIFF_SEC(current_time, wdNode->current_state_time); seconds_since_node_startup = WD_TIME_DIFF_SEC(current_time, wdNode->startup_time); - JsonNode* jNode = jw_create_with_object(true); + JsonNode *jNode = jw_create_with_object(true); jw_put_int(jNode, "State", wdNode->state); jw_put_int(jNode, "WdPort", wdNode->wd_port); jw_put_int(jNode, "PgpoolPort", wdNode->pgpool_port); jw_put_int(jNode, "WdPriority", wdNode->wd_priority); - jw_put_string(jNode, "NodeName",wdNode->nodeName); - jw_put_string(jNode, "HostName",wdNode->hostname); - jw_put_string(jNode, "VIP",wdNode->delegate_ip); + jw_put_string(jNode, "NodeName", wdNode->nodeName); + jw_put_string(jNode, "HostName", wdNode->hostname); + jw_put_string(jNode, "VIP", wdNode->delegate_ip); jw_put_long(jNode, "SecondsSinceStartup", seconds_since_node_startup); jw_put_long(jNode, "SecondsSinceCurrentState", seconds_since_current_state); jw_put_int(jNode, "QuorumStatus", wdNode->quorum_status); jw_put_int(jNode, "AliveNodeCount", wdNode->standby_nodes_count); - jw_put_bool(jNode, "Escalated", wdNode->escalated == 0?false:true); + jw_put_bool(jNode, "Escalated", wdNode->escalated == 0 ? false : true); - if(authkey) - jw_put_string(jNode, "authkey",authkey); + if (authkey) + jw_put_string(jNode, "authkey", authkey); jw_finish_document(jNode); json_str = pstrdup(jw_get_json_string(jNode)); @@ -446,27 +460,28 @@ char* get_watchdog_node_info_json(WatchdogNode* wdNode, char* authkey) } -WatchdogNode* get_watchdog_node_from_json(char* json_data, int data_len, char** authkey) +WatchdogNode * +get_watchdog_node_from_json(char *json_data, int data_len, char **authkey) { json_value *root = NULL; - char* ptr; - WatchdogNode* wdNode = palloc0(sizeof(WatchdogNode)); + char *ptr; + WatchdogNode *wdNode = palloc0(sizeof(WatchdogNode)); - root = json_parse(json_data,data_len); + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) goto ERROR_EXIT; if (json_get_long_value_for_key(root, "StartupTimeSecs", &wdNode->startup_time.tv_sec)) { - bool escalated; - long seconds_since_node_startup; - long seconds_since_current_state; + bool escalated; + long seconds_since_node_startup; + long seconds_since_current_state; struct timeval current_time; - gettimeofday(&current_time,NULL); + gettimeofday(&current_time, NULL); - /*The new version does not have StartupTimeSecs Key */ + /* The new version does not have StartupTimeSecs Key */ if (json_get_long_value_for_key(root, "SecondsSinceStartup", &seconds_since_node_startup)) goto ERROR_EXIT; if (json_get_long_value_for_key(root, "SecondsSinceCurrentState", &seconds_since_current_state)) @@ -490,11 +505,11 @@ WatchdogNode* get_watchdog_node_from_json(char* json_data, int data_len, char** } else { - /* we do this to know that we got the info from older version*/ + /* we do this to know that we got the info from older version */ wdNode->current_state_time.tv_sec = 0; } - if (json_get_int_value_for_key(root, "State", (int*)&wdNode->state)) + if (json_get_int_value_for_key(root, "State", (int *) &wdNode->state)) goto ERROR_EXIT; if (json_get_int_value_for_key(root, "WdPort", &wdNode->wd_port)) goto ERROR_EXIT; @@ -507,17 +522,17 @@ WatchdogNode* get_watchdog_node_from_json(char* json_data, int data_len, char** ptr = json_get_string_value_for_key(root, "NodeName"); if (ptr == NULL) goto ERROR_EXIT; - strncpy(wdNode->nodeName, ptr, sizeof(wdNode->nodeName) -1); + strncpy(wdNode->nodeName, ptr, sizeof(wdNode->nodeName) - 1); ptr = json_get_string_value_for_key(root, "HostName"); if (ptr == NULL) goto ERROR_EXIT; - strncpy(wdNode->hostname, ptr, sizeof(wdNode->hostname) -1); + strncpy(wdNode->hostname, ptr, sizeof(wdNode->hostname) - 1); ptr = json_get_string_value_for_key(root, "VIP"); if (ptr == NULL) goto ERROR_EXIT; - strncpy(wdNode->delegate_ip, ptr, sizeof(wdNode->delegate_ip) -1); + strncpy(wdNode->delegate_ip, ptr, sizeof(wdNode->delegate_ip) - 1); if (authkey) { @@ -529,24 +544,25 @@ WatchdogNode* get_watchdog_node_from_json(char* json_data, int data_len, char** } return wdNode; - ERROR_EXIT: +ERROR_EXIT: if (root) json_value_free(root); pfree(wdNode); return NULL; } -bool parse_beacon_message_json(char* json_data, int data_len, - int* state, - long* seconds_since_node_startup, - long* seconds_since_current_state, - int* quorumStatus, - int* standbyNodesCount, - bool* escalated) +bool +parse_beacon_message_json(char *json_data, int data_len, + int *state, + long *seconds_since_node_startup, + long *seconds_since_current_state, + int *quorumStatus, + int *standbyNodesCount, + bool *escalated) { json_value *root = NULL; - root = json_parse(json_data,data_len); + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) goto ERROR_EXIT; @@ -575,18 +591,19 @@ ERROR_EXIT: return false; } -char* get_lifecheck_node_status_change_json(int nodeID, int nodeStatus, char* message, char* authKey) +char * +get_lifecheck_node_status_change_json(int nodeID, int nodeStatus, char *message, char *authKey) { - char* json_str; - JsonNode* jNode = jw_create_with_object(true); + char *json_str; + JsonNode *jNode = jw_create_with_object(true); if (authKey != NULL && strlen(authKey) > 0) - jw_put_string(jNode, WD_IPC_AUTH_KEY, authKey); /* put the auth key*/ + jw_put_string(jNode, WD_IPC_AUTH_KEY, authKey); /* put the auth key */ /* add the node ID */ jw_put_int(jNode, "NodeID", nodeID); /* add the node status */ - jw_put_int(jNode, "NodeStatus",nodeStatus); + jw_put_int(jNode, "NodeStatus", nodeStatus); /* add the node message if any */ if (message) jw_put_string(jNode, "Message", message); @@ -597,11 +614,13 @@ char* get_lifecheck_node_status_change_json(int nodeID, int nodeStatus, char* me return json_str; } -bool parse_node_status_json(char* json_data, int data_len, int* nodeID, int* nodeStatus, char** message) +bool +parse_node_status_json(char *json_data, int data_len, int *nodeID, int *nodeStatus, char **message) { - json_value* root; - char* ptr = NULL; - root = json_parse(json_data,data_len); + json_value *root; + char *ptr = NULL; + + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) @@ -626,56 +645,58 @@ ERROR_EXIT: return false; } -WDNodeInfo* get_WDNodeInfo_from_wd_node_json(json_value* source) +WDNodeInfo * +get_WDNodeInfo_from_wd_node_json(json_value * source) { - char* ptr; - WDNodeInfo* wdNodeInfo = palloc0(sizeof(WDNodeInfo)); + char *ptr; + WDNodeInfo *wdNodeInfo = palloc0(sizeof(WDNodeInfo)); + if (source->type != json_object) ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("node is not of object type"))); - + if (json_get_int_value_for_key(source, "ID", &wdNodeInfo->id)) { ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find Watchdog Node ID"))); } - + ptr = json_get_string_value_for_key(source, "NodeName"); if (ptr == NULL) { ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find Watchdog Node Name"))); } - strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) -1); - + strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) - 1); + ptr = json_get_string_value_for_key(source, "HostName"); if (ptr == NULL) { ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find Watchdog Host Name"))); } - strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) -1); - + strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) - 1); + ptr = json_get_string_value_for_key(source, "DelegateIP"); if (ptr == NULL) { ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find Watchdog delegate IP"))); } - strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) -1); - + strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) - 1); + if (json_get_int_value_for_key(source, "WdPort", &wdNodeInfo->wd_port)) { ereport(ERROR, (errmsg("invalid json data"), errdetail("unable to find WdPort"))); } - + if (json_get_int_value_for_key(source, "PgpoolPort", &wdNodeInfo->pgpool_port)) { ereport(ERROR, @@ -694,10 +715,10 @@ WDNodeInfo* get_WDNodeInfo_from_wd_node_json(json_value* source) if (ptr == NULL) { ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find Watchdog State Name"))); } - strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) -1); + strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) - 1); if (json_get_int_value_for_key(source, "Priority", &wdNodeInfo->wd_priority)) { @@ -705,29 +726,31 @@ WDNodeInfo* get_WDNodeInfo_from_wd_node_json(json_value* source) (errmsg("invalid json data"), errdetail("unable to find state"))); } - + return wdNodeInfo; - + } -char* get_wd_node_function_json(char* func_name, int *node_id_set, int count, unsigned char flags, unsigned int sharedKey, char* authKey) +char * +get_wd_node_function_json(char *func_name, int *node_id_set, int count, unsigned char flags, unsigned int sharedKey, char *authKey) { - char* json_str; - int i; - JsonNode* jNode = jw_create_with_object(true); + char *json_str; + int i; + JsonNode *jNode = jw_create_with_object(true); - jw_put_int(jNode, WD_IPC_SHARED_KEY, sharedKey); /* put the shared key*/ + jw_put_int(jNode, WD_IPC_SHARED_KEY, sharedKey); /* put the shared key */ if (authKey != NULL && strlen(authKey) > 0) - jw_put_string(jNode, WD_IPC_AUTH_KEY, authKey); /* put the auth key*/ + jw_put_string(jNode, WD_IPC_AUTH_KEY, authKey); /* put the auth key */ jw_put_string(jNode, "Function", func_name); - jw_put_int(jNode, "Flags", (int)flags); + jw_put_int(jNode, "Flags", (int) flags); jw_put_int(jNode, "NodeCount", count); if (count > 0) { jw_start_array(jNode, "NodeIdList"); - for (i=0; i < count; i++) { + for (i = 0; i < count; i++) + { jw_put_int_value(jNode, node_id_set[i]); } jw_end_element(jNode); @@ -738,26 +761,28 @@ char* get_wd_node_function_json(char* func_name, int *node_id_set, int count, un return json_str; } -bool parse_wd_node_function_json(char* json_data, int data_len, char** func_name, int **node_id_set, int *count, unsigned char *flags) +bool +parse_wd_node_function_json(char *json_data, int data_len, char **func_name, int **node_id_set, int *count, unsigned char *flags) { - json_value *root, *value; - char* ptr; - int node_count = 0; - int i; + json_value *root, + *value; + char *ptr; + int node_count = 0; + int i; *node_id_set = NULL; *func_name = NULL; *count = 0; - root = json_parse(json_data,data_len); + root = json_parse(json_data, data_len); /* The root node must be object */ if (root == NULL || root->type != json_object) { json_value_free(root); ereport(LOG, - (errmsg("watchdog is unable to parse node function json"), - errdetail("invalid json data \"%.*s\"",data_len,json_data))); + (errmsg("watchdog is unable to parse node function json"), + errdetail("invalid json data \"%.*s\"", data_len, json_data))); return false; } ptr = json_get_string_value_for_key(root, "Function"); @@ -765,21 +790,21 @@ bool parse_wd_node_function_json(char* json_data, int data_len, char** func_name { json_value_free(root); ereport(LOG, - (errmsg("watchdog is unable to parse node function json"), - errdetail("function node not found in json data \"%s\"",json_data))); + (errmsg("watchdog is unable to parse node function json"), + errdetail("function node not found in json data \"%s\"", json_data))); return false; } *func_name = pstrdup(ptr); - /* If it is a node function ?*/ + /* If it is a node function ? */ if (json_get_int_value_for_key(root, "Flags", flags)) { - /*node count not found, But we don't care much about this*/ + /* node count not found, But we don't care much about this */ *flags = 0; /* it may be from the old version */ } if (json_get_int_value_for_key(root, "NodeCount", &node_count)) { - /*node count not found, But we don't care much about this*/ + /* node count not found, But we don't care much about this */ json_value_free(root); return true; } @@ -790,12 +815,12 @@ bool parse_wd_node_function_json(char* json_data, int data_len, char** func_name } *count = node_count; - value = json_get_value_for_key(root,"NodeIdList"); + value = json_get_value_for_key(root, "NodeIdList"); if (value == NULL) { json_value_free(root); ereport(LOG, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find NodeIdList node from data"))); return false; } @@ -812,7 +837,7 @@ bool parse_wd_node_function_json(char* json_data, int data_len, char** func_name json_value_free(root); ereport(WARNING, (errmsg("invalid json data"), - errdetail("NodeIdList array contains %d nodes while expecting %d",value->u.array.length, node_count))); + errdetail("NodeIdList array contains %d nodes while expecting %d", value->u.array.length, node_count))); return false; } @@ -825,10 +850,11 @@ bool parse_wd_node_function_json(char* json_data, int data_len, char** func_name return true; } -char* get_wd_simple_message_json(char* message) +char * +get_wd_simple_message_json(char *message) { - char* json_str; - JsonNode* jNode = jw_create_with_object(true); + char *json_str; + JsonNode *jNode = jw_create_with_object(true); jw_put_string(jNode, "MESSAGE", message); jw_finish_document(jNode); @@ -836,4 +862,3 @@ char* get_wd_simple_message_json(char* message) jw_destroy(jNode); return json_str; } - diff --git a/src/watchdog/wd_lifecheck.c b/src/watchdog/wd_lifecheck.c index 4312787b6..a9790d48c 100644 --- a/src/watchdog/wd_lifecheck.c +++ b/src/watchdog/wd_lifecheck.c @@ -48,48 +48,50 @@ #include "libpq-fe.h" -#define LIFECHECK_GETNODE_WAIT_SEC_COUNT 5 /* max number of seconds the lifecheck process - * should waits before giving up - * while fetching the configured watchdog node - * infromation from watchdog process through IPC channel - */ +#define LIFECHECK_GETNODE_WAIT_SEC_COUNT 5 /* max number of seconds the + * lifecheck process should waits + * before giving up while fetching + * the configured watchdog node + * infromation from watchdog + * process through IPC channel */ /* * thread argument for lifecheck of pgpool */ -typedef struct { +typedef struct +{ LifeCheckNode *lifeCheckNode; - int retry; /* retry times (not used?)*/ -} WdPgpoolThreadArg; + int retry; /* retry times (not used?) */ +} WdPgpoolThreadArg; typedef struct WdUpstreamConnectionData { - char* hostname; /* host name of server */ - pid_t pid; /* pid of ping process */ - bool reachable; /* true if last ping was successful */ - int outputfd; /* pipe fd linked to output of ping process */ -}WdUpstreamConnectionData; + char *hostname; /* host name of server */ + pid_t pid; /* pid of ping process */ + bool reachable; /* true if last ping was successful */ + int outputfd; /* pipe fd linked to output of ping process */ +} WdUpstreamConnectionData; -List* g_trusted_server_list = NIL; +List *g_trusted_server_list = NIL; static void wd_initialize_trusted_servers_list(void); static bool wd_ping_all_server(void); -static WdUpstreamConnectionData* wd_get_server_from_pid(pid_t pid); +static WdUpstreamConnectionData * wd_get_server_from_pid(pid_t pid); -static void * thread_ping_pgpool(void * arg); -static PGconn * create_conn(char * hostname, int port); +static void *thread_ping_pgpool(void *arg); +static PGconn *create_conn(char *hostname, int port); static pid_t lifecheck_main(void); static void check_pgpool_status(void); static void check_pgpool_status_by_query(void); static void check_pgpool_status_by_hb(void); -static int ping_pgpool(PGconn * conn); -static int is_parent_alive(void); +static int ping_pgpool(PGconn *conn); +static int is_parent_alive(void); static bool fetch_watchdog_nodes_data(void); -static int wd_check_heartbeat(LifeCheckNode* node); +static int wd_check_heartbeat(LifeCheckNode * node); -static void load_watchdog_nodes_from_json(char* json_data, int len); +static void load_watchdog_nodes_from_json(char *json_data, int len); static void spawn_lifecheck_children(void); static RETSIGTYPE lifecheck_exit_handler(int sig); @@ -97,18 +99,19 @@ static RETSIGTYPE reap_handler(int sig); static pid_t wd_reaper_lifecheck(pid_t pid, int status); static bool lifecheck_kill_all_children(int sig); -static const char* lifecheck_child_name(pid_t pid); +static const char *lifecheck_child_name(pid_t pid); static void reaper(void); -static int is_wd_lifecheck_ready(void); -static int wd_lifecheck(void); -static int wd_ping_pgpool(LifeCheckNode* node); +static int is_wd_lifecheck_ready(void); +static int wd_lifecheck(void); +static int wd_ping_pgpool(LifeCheckNode * node); static pid_t fork_lifecheck_child(void); -LifeCheckCluster* gslifeCheckCluster = NULL; /* lives in shared memory */ +LifeCheckCluster *gslifeCheckCluster = NULL; /* lives in shared memory */ -pid_t *g_hb_receiver_pid = NULL; /* Array of heart beat receiver child pids */ -pid_t *g_hb_sender_pid = NULL; /* Array of heart beat sender child pids */ +pid_t *g_hb_receiver_pid = NULL; /* Array of heart beat receiver child + * pids */ +pid_t *g_hb_sender_pid = NULL; /* Array of heart beat sender child pids */ static volatile sig_atomic_t sigchld_request = 0; @@ -123,9 +126,11 @@ static RETSIGTYPE reap_handler(int sig) } -static const char* lifecheck_child_name(pid_t pid) +static const char * +lifecheck_child_name(pid_t pid) { - int i; + int i; + for (i = 0; i < pool_config->num_hb_if; i++) { if (g_hb_receiver_pid && pid == g_hb_receiver_pid[i]) @@ -134,17 +139,19 @@ static const char* lifecheck_child_name(pid_t pid) return "heartBeat sender"; } /* Check if it was a ping to trusted server process */ - WdUpstreamConnectionData* server = wd_get_server_from_pid(pid); + WdUpstreamConnectionData *server = wd_get_server_from_pid(pid); + if (server) return "trusted host ping process"; return "unknown"; } -static void reaper(void) +static void +reaper(void) { - pid_t pid; - int status; - + pid_t pid; + int status; + ereport(DEBUG1, (errmsg("Lifecheck child reaper handler"))); @@ -154,7 +161,8 @@ static void reaper(void) while ((pid = pool_waitpid(&status)) > 0) { /* First check if it is the trusted server ping process */ - WdUpstreamConnectionData* server = wd_get_server_from_pid(pid); + WdUpstreamConnectionData *server = wd_get_server_from_pid(pid); + if (server) { server->reachable = wd_get_ping_result(server->hostname, status, server->outputfd); @@ -162,23 +170,23 @@ static void reaper(void) close(server->outputfd); } else - wd_reaper_lifecheck(pid,status); + wd_reaper_lifecheck(pid, status); } } static pid_t wd_reaper_lifecheck(pid_t pid, int status) { - int i; - bool restart_child = true; - const char* proc_name = lifecheck_child_name(pid); + int i; + bool restart_child = true; + const char *proc_name = lifecheck_child_name(pid); - if(WIFEXITED(status)) + if (WIFEXITED(status)) { - if(WEXITSTATUS(status) == POOL_EXIT_FATAL) + if (WEXITSTATUS(status) == POOL_EXIT_FATAL) ereport(LOG, - (errmsg("lifecheck child process (%s) with pid: %d exit with FATAL ERROR.",proc_name, pid))); - else if(WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) + (errmsg("lifecheck child process (%s) with pid: %d exit with FATAL ERROR.", proc_name, pid))); + else if (WEXITSTATUS(status) == POOL_EXIT_NO_RESTART) { restart_child = false; ereport(LOG, @@ -188,16 +196,16 @@ wd_reaper_lifecheck(pid_t pid, int status) if (WIFSIGNALED(status)) { /* Child terminated by segmentation fault. Report it */ - if(WTERMSIG(status) == SIGSEGV) + if (WTERMSIG(status) == SIGSEGV) ereport(WARNING, - (errmsg("lifecheck child process (%s) with pid: %d was terminated by segmentation fault",proc_name,pid))); + (errmsg("lifecheck child process (%s) with pid: %d was terminated by segmentation fault", proc_name, pid))); else ereport(LOG, (errmsg("lifecheck child process (%s) with pid: %d exits with status %d by signal %d", proc_name, pid, status, WTERMSIG(status)))); } else ereport(LOG, - (errmsg("lifecheck child process (%s) with pid: %d exits with status %d",proc_name, pid, status))); + (errmsg("lifecheck child process (%s) with pid: %d exits with status %d", proc_name, pid, status))); if (g_hb_receiver_pid == NULL && g_hb_sender_pid == NULL) return -1; @@ -206,57 +214,60 @@ wd_reaper_lifecheck(pid_t pid, int status) { if (g_hb_receiver_pid && pid == g_hb_receiver_pid[i]) { - if(restart_child) + if (restart_child) { g_hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_if[i])); ereport(LOG, - (errmsg("fork a new %s process with pid: %d",proc_name, g_hb_receiver_pid[i]))); + (errmsg("fork a new %s process with pid: %d", proc_name, g_hb_receiver_pid[i]))); } else g_hb_receiver_pid[i] = 0; - + return g_hb_receiver_pid[i]; } - + else if (g_hb_sender_pid && pid == g_hb_sender_pid[i]) { - if(restart_child) + if (restart_child) { g_hb_sender_pid[i] = wd_hb_sender(1, &(pool_config->hb_if[i])); ereport(LOG, - (errmsg("fork a new %s process with pid: %d",proc_name, g_hb_sender_pid[i]))); + (errmsg("fork a new %s process with pid: %d", proc_name, g_hb_sender_pid[i]))); } else g_hb_sender_pid[i] = 0; - + return g_hb_sender_pid[i]; } } return -1; } -static bool lifecheck_kill_all_children(int sig) +static bool +lifecheck_kill_all_children(int sig) { - bool ret = false; + bool ret = false; + if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB && g_hb_receiver_pid && g_hb_sender_pid) { - int i; + int i; + for (i = 0; i < pool_config->num_hb_if; i++) { - pid_t pid_child = g_hb_receiver_pid[i]; + pid_t pid_child = g_hb_receiver_pid[i]; if (pid_child > 0) { - kill(pid_child,sig); + kill(pid_child, sig); ret = true; } pid_child = g_hb_sender_pid[i]; - + if (pid_child > 0) { - kill(pid_child,sig); + kill(pid_child, sig); ret = true; } } @@ -267,14 +278,14 @@ static bool lifecheck_kill_all_children(int sig) static RETSIGTYPE lifecheck_exit_handler(int sig) { - pid_t wpid; - bool child_killed; + pid_t wpid; + bool child_killed; POOL_SETMASK(&AuthBlockSig); ereport(DEBUG1, (errmsg("lifecheck child receives shutdown request signal %d, forwarding to all children", sig))); - - if (sig == SIGTERM) /* smart shutdown */ + + if (sig == SIGTERM) /* smart shutdown */ { ereport(DEBUG1, (errmsg("lifecheck child receives smart shutdown request"))); @@ -299,15 +310,15 @@ lifecheck_exit_handler(int sig) do { wpid = wait(NULL); - }while (wpid > 0 || (wpid == -1 && errno == EINTR)); - + } while (wpid > 0 || (wpid == -1 && errno == EINTR)); + if (wpid == -1 && errno != ECHILD) ereport(WARNING, (errmsg("wait() on lifecheck children failed. reason:%s", strerror(errno)))); if (g_hb_receiver_pid) pfree(g_hb_receiver_pid); - + if (g_hb_sender_pid) pfree(g_hb_sender_pid); @@ -317,11 +328,12 @@ lifecheck_exit_handler(int sig) exit(0); } -pid_t initialize_watchdog_lifecheck(void) +pid_t +initialize_watchdog_lifecheck(void) { if (!pool_config->use_watchdog) return 0; - + if (pool_config->wd_lifecheck_method == LIFECHECK_BY_EXTERNAL) return 0; @@ -331,19 +343,20 @@ pid_t initialize_watchdog_lifecheck(void) /* * fork a child for lifecheck */ -static pid_t fork_lifecheck_child(void) +static pid_t +fork_lifecheck_child(void) { - pid_t pid; - + pid_t pid; + pid = fork(); - + if (pid == 0) { on_exit_reset(); /* Set the process type variable */ processType = PT_LIFECHECK; - + /* call PCP child main */ POOL_SETMASK(&UnBlockSig); lifecheck_main(); @@ -353,7 +366,7 @@ static pid_t fork_lifecheck_child(void) ereport(FATAL, (errmsg("fork() failed. reason: %s", strerror(errno)))); } - + return pid; } @@ -363,11 +376,11 @@ static pid_t lifecheck_main(void) { sigjmp_buf local_sigjmp_buf; - int i; + int i; ereport(DEBUG1, - (errmsg("I am watchdog lifecheck child with pid:%d",getpid()))); - + (errmsg("I am watchdog lifecheck child with pid:%d", getpid()))); + /* Identify myself via ps */ init_ps_display("", "", "", ""); @@ -384,15 +397,15 @@ lifecheck_main(void) ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); - + MemoryContextSwitchTo(TopMemoryContext); - set_ps_display("lifecheck",false); + set_ps_display("lifecheck", false); - /* Get the list of watchdog node to monitor - * from watchdog process + /* + * Get the list of watchdog node to monitor from watchdog process */ - for (i =0; i < LIFECHECK_GETNODE_WAIT_SEC_COUNT; i++) + for (i = 0; i < LIFECHECK_GETNODE_WAIT_SEC_COUNT; i++) { if (fetch_watchdog_nodes_data() == true) break; @@ -420,16 +433,16 @@ lifecheck_main(void) { /* Since not using PG_TRY, must reset error stack by hand */ error_context_stack = NULL; - + EmitErrorReport(); MemoryContextSwitchTo(TopMemoryContext); FlushErrorState(); sleep(pool_config->wd_heartbeat_keepalive); } - + /* We can now handle ereport(ERROR) */ PG_exception_stack = &local_sigjmp_buf; - + /* watchdog loop */ for (;;) { @@ -447,11 +460,13 @@ lifecheck_main(void) return 0; } -static void spawn_lifecheck_children(void) +static void +spawn_lifecheck_children(void) { if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB) { - int i; + int i; + g_hb_receiver_pid = palloc0(sizeof(pid_t) * pool_config->num_hb_if); g_hb_sender_pid = palloc0(sizeof(pid_t) * pool_config->num_hb_if); @@ -466,17 +481,19 @@ static void spawn_lifecheck_children(void) } } -static void print_lifecheck_cluster(void) +static void +print_lifecheck_cluster(void) { - int i; + int i; + if (!gslifeCheckCluster) return; ereport(LOG, - (errmsg("%d watchdog nodes are configured for lifecheck",gslifeCheckCluster->nodeCount))); - for (i = 0; i< gslifeCheckCluster->nodeCount; i++) + (errmsg("%d watchdog nodes are configured for lifecheck", gslifeCheckCluster->nodeCount))); + for (i = 0; i < gslifeCheckCluster->nodeCount; i++) { ereport(LOG, - (errmsg("watchdog nodes ID:%d Name:\"%s\"",gslifeCheckCluster->lifeCheckNodes[i].ID,gslifeCheckCluster->lifeCheckNodes[i].nodeName), + (errmsg("watchdog nodes ID:%d Name:\"%s\"", gslifeCheckCluster->lifeCheckNodes[i].ID, gslifeCheckCluster->lifeCheckNodes[i].nodeName), errdetail("Host:\"%s\" WD Port:%d pgpool-II port:%d", gslifeCheckCluster->lifeCheckNodes[i].hostName, gslifeCheckCluster->lifeCheckNodes[i].wdPort, @@ -484,12 +501,14 @@ static void print_lifecheck_cluster(void) } } -static bool inform_node_status(LifeCheckNode* node, char *message) +static bool +inform_node_status(LifeCheckNode * node, char *message) { - int node_status,x; - char* json_data; - WDIPCCmdResult* res = NULL; - char* new_status; + int node_status, + x; + char *json_data; + WDIPCCmdResult *res = NULL; + char *new_status; if (node->nodeState == NODE_DEAD) { @@ -506,15 +525,15 @@ static bool inform_node_status(LifeCheckNode* node, char *message) ereport(LOG, (errmsg("informing the node status change to watchdog"), - errdetail("node id :%d status = \"%s\" message:\"%s\"",node->ID,new_status,message))); + errdetail("node id :%d status = \"%s\" message:\"%s\"", node->ID, new_status, message))); json_data = get_lifecheck_node_status_change_json(node->ID, node_status, message, pool_config->wd_authkey); if (json_data == NULL) return false; - for (x=0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) + for (x = 0; x < MAX_SEC_WAIT_FOR_CLUSTER_TRANSATION; x++) { - res = issue_command_to_watchdog(WD_NODE_STATUS_CHANGE_COMMAND ,0, json_data, strlen(json_data),false); + res = issue_command_to_watchdog(WD_NODE_STATUS_CHANGE_COMMAND, 0, json_data, strlen(json_data), false); if (res) break; sleep(1); @@ -528,46 +547,50 @@ static bool inform_node_status(LifeCheckNode* node, char *message) return false; } -static bool fetch_watchdog_nodes_data(void) +static bool +fetch_watchdog_nodes_data(void) { - char* json_data = wd_get_watchdog_nodes(-1); + char *json_data = wd_get_watchdog_nodes(-1); + if (json_data == NULL) { ereport(ERROR, (errmsg("get node list command reply contains no data"))); return false; } - load_watchdog_nodes_from_json(json_data,strlen(json_data)); + load_watchdog_nodes_from_json(json_data, strlen(json_data)); pfree(json_data); return true; } -static void load_watchdog_nodes_from_json(char* json_data, int len) +static void +load_watchdog_nodes_from_json(char *json_data, int len) { - json_value* root; - json_value* value; - int i,nodeCount; + json_value *root; + json_value *value; + int i, + nodeCount; - root = json_parse(json_data,len); + root = json_parse(json_data, len); /* The root node must be object */ if (root == NULL || root->type != json_object) { json_value_free(root); ereport(ERROR, - (errmsg("unable to parse json data for node list"))); + (errmsg("unable to parse json data for node list"))); } if (json_get_int_value_for_key(root, "NodeCount", &nodeCount)) { json_value_free(root); ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("unable to find NodeCount node from data"))); } /* find the WatchdogNodes array */ - value = json_get_value_for_key(root,"WatchdogNodes"); + value = json_get_value_for_key(root, "WatchdogNodes"); if (value == NULL) { json_value_free(root); @@ -579,15 +602,15 @@ static void load_watchdog_nodes_from_json(char* json_data, int len) { json_value_free(root); ereport(ERROR, - (errmsg("invalid json data"), + (errmsg("invalid json data"), errdetail("WatchdogNodes node does not contains Array"))); } if (nodeCount != value->u.array.length) { json_value_free(root); ereport(ERROR, - (errmsg("invalid json data"), - errdetail("WatchdogNodes array contains %d nodes while expecting %d",value->u.array.length, nodeCount))); + (errmsg("invalid json data"), + errdetail("WatchdogNodes array contains %d nodes while expecting %d", value->u.array.length, nodeCount))); } /* okay we are done, put this in shared memory */ @@ -612,39 +635,41 @@ static void load_watchdog_nodes_from_json(char* json_data, int len) } -static int is_wd_lifecheck_ready(void) +static int +is_wd_lifecheck_ready(void) { - int rtn = WD_OK; - int i; + int rtn = WD_OK; + int i; - for (i = 0; i< gslifeCheckCluster->nodeCount; i++) + for (i = 0; i < gslifeCheckCluster->nodeCount; i++) { - LifeCheckNode* node = &gslifeCheckCluster->lifeCheckNodes[i]; + LifeCheckNode *node = &gslifeCheckCluster->lifeCheckNodes[i]; + /* query mode */ if (pool_config->wd_lifecheck_method == LIFECHECK_BY_QUERY) { if (wd_ping_pgpool(node) == WD_NG) { ereport(DEBUG1, - (errmsg("watchdog checking life check is ready"), - errdetail("pgpool:%d at \"%s:%d\" has not started yet", - i, node->hostName, node->pgpoolPort))); + (errmsg("watchdog checking life check is ready"), + errdetail("pgpool:%d at \"%s:%d\" has not started yet", + i, node->hostName, node->pgpoolPort))); rtn = WD_NG; } } /* heartbeat mode */ else if (pool_config->wd_lifecheck_method == LIFECHECK_BY_HB) { - if (node->ID == 0) /* local node */ + if (node->ID == 0) /* local node */ continue; if (!WD_TIME_ISSET(node->hb_last_recv_time) || - !WD_TIME_ISSET(node->hb_send_time)) + !WD_TIME_ISSET(node->hb_send_time)) { ereport(DEBUG1, - (errmsg("watchdog checking life check is ready"), - errdetail("pgpool:%d at \"%s:%d\" has not send the heartbeat signal yet", - i, node->hostName, node->pgpoolPort))); + (errmsg("watchdog checking life check is ready"), + errdetail("pgpool:%d at \"%s:%d\" has not send the heartbeat signal yet", + i, node->hostName, node->pgpoolPort))); rtn = WD_NG; } } @@ -652,7 +677,7 @@ static int is_wd_lifecheck_ready(void) else { ereport(ERROR, - (errmsg("checking if watchdog is ready, unkown watchdog mode \"%d\"", + (errmsg("checking if watchdog is ready, unkown watchdog mode \"%d\"", pool_config->wd_lifecheck_method))); } } @@ -663,14 +688,15 @@ static int is_wd_lifecheck_ready(void) /* * Check if pgpool is living */ -static int wd_lifecheck(void) +static int +wd_lifecheck(void) { /* check upper connection */ if (strlen(pool_config->trusted_servers)) { - if(wd_ping_all_server() == false) + if (wd_ping_all_server() == false) { - LifeCheckNode* node = &gslifeCheckCluster->lifeCheckNodes[0]; + LifeCheckNode *node = &gslifeCheckCluster->lifeCheckNodes[0]; if (node->nodeState != NODE_DEAD) { @@ -678,7 +704,7 @@ static int wd_lifecheck(void) ereport(WARNING, (errmsg("watchdog lifecheck, failed to connect to any trusted servers"))); - inform_node_status(node,"trusted server is unreachable"); + inform_node_status(node, "trusted server is unreachable"); } return WD_NG; } @@ -717,9 +743,10 @@ check_pgpool_status() static void check_pgpool_status_by_hb(void) { - int i; + int i; struct timeval tv; - LifeCheckNode* node = &gslifeCheckCluster->lifeCheckNodes[0]; + LifeCheckNode *node = &gslifeCheckCluster->lifeCheckNodes[0]; + gettimeofday(&tv, NULL); /* about myself */ @@ -729,39 +756,39 @@ check_pgpool_status_by_hb(void) node->nodeState = NODE_DEAD; ereport(LOG, (errmsg("checking pgpool status by heartbeat"), - errdetail("lifecheck failed. pgpool (%s:%d) seems not to be working", + errdetail("lifecheck failed. pgpool (%s:%d) seems not to be working", node->hostName, node->pgpoolPort))); - inform_node_status(node,"parent process is dead"); + inform_node_status(node, "parent process is dead"); } - - for (i = 1; i< gslifeCheckCluster->nodeCount; i++) + + for (i = 1; i < gslifeCheckCluster->nodeCount; i++) { node = &gslifeCheckCluster->lifeCheckNodes[i]; ereport(DEBUG1, - (errmsg("watchdog life checking by heartbeat"), - errdetail("checking pgpool %d (%s:%d)", - i, node->hostName, node->pgpoolPort))); + (errmsg("watchdog life checking by heartbeat"), + errdetail("checking pgpool %d (%s:%d)", + i, node->hostName, node->pgpoolPort))); if (wd_check_heartbeat(node) == WD_NG) { ereport(DEBUG2, - (errmsg("checking pgpool status by heartbeat"), + (errmsg("checking pgpool status by heartbeat"), errdetail("lifecheck failed. pgpool: %d at \"%s:%d\" seems not to be working", i, node->hostName, node->pgpoolPort))); - + if (node->nodeState != NODE_DEAD) { node->nodeState = NODE_DEAD; - inform_node_status(node,"No heartbeat signal from node"); + inform_node_status(node, "No heartbeat signal from node"); } } else { ereport(DEBUG1, - (errmsg("checking pgpool status by heartbeat"), + (errmsg("checking pgpool status by heartbeat"), errdetail("OK; status OK"))); } } @@ -771,37 +798,39 @@ static void check_pgpool_status_by_query(void) { pthread_attr_t attr; - pthread_t thread[MAX_WATCHDOG_NUM]; + pthread_t thread[MAX_WATCHDOG_NUM]; WdPgpoolThreadArg thread_arg[MAX_WATCHDOG_NUM]; - LifeCheckNode* node; - int rc,i; + LifeCheckNode *node; + int rc, + i; /* thread init */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* send queries to all pgpools using threads */ - for (i = 0; i< gslifeCheckCluster->nodeCount; i++) + for (i = 0; i < gslifeCheckCluster->nodeCount; i++) { node = &gslifeCheckCluster->lifeCheckNodes[i]; thread_arg[i].lifeCheckNode = node; - rc = watchdog_thread_create(&thread[i], &attr, thread_ping_pgpool, (void*)&thread_arg[i]); + rc = watchdog_thread_create(&thread[i], &attr, thread_ping_pgpool, (void *) &thread_arg[i]); } pthread_attr_destroy(&attr); /* check results of queries */ - for (i = 0; i< gslifeCheckCluster->nodeCount; i++) + for (i = 0; i < gslifeCheckCluster->nodeCount; i++) { - int result; + int result; + node = &gslifeCheckCluster->lifeCheckNodes[i]; ereport(DEBUG1, (errmsg("checking pgpool status by query"), - errdetail("checking pgpool %d (%s:%d)", + errdetail("checking pgpool %d (%s:%d)", i, node->hostName, node->pgpoolPort))); - rc = pthread_join(thread[i], (void **)&result); + rc = pthread_join(thread[i], (void **) &result); if ((rc != 0) && (errno == EINTR)) { usleep(100); @@ -811,7 +840,7 @@ check_pgpool_status_by_query(void) if (result == WD_OK) { ereport(DEBUG1, - (errmsg("checking pgpool status by query"), + (errmsg("checking pgpool status by query"), errdetail("WD_OK: status: %d", node->nodeState))); /* life point init */ @@ -820,19 +849,19 @@ check_pgpool_status_by_query(void) else { ereport(DEBUG1, - (errmsg("checking pgpool status by query"), + (errmsg("checking pgpool status by query"), errdetail("NG; status: %d life:%d", node->nodeState, node->retry_lives))); if (node->retry_lives > 0) { - node->retry_lives --; + node->retry_lives--; } /* pgpool goes down */ if (node->retry_lives <= 0) { ereport(LOG, - (errmsg("checking pgpool status by query"), - errdetail("lifecheck failed %d times. pgpool %d (%s:%d) seems not to be working", + (errmsg("checking pgpool status by query"), + errdetail("lifecheck failed %d times. pgpool %d (%s:%d) seems not to be working", pool_config->wd_life_point, i, node->hostName, node->pgpoolPort))); if (node->nodeState == NODE_DEAD) @@ -840,9 +869,9 @@ check_pgpool_status_by_query(void) node->nodeState = NODE_DEAD; /* It's me! */ if (i == 0) - inform_node_status(node,"parent process is dead"); + inform_node_status(node, "parent process is dead"); else - inform_node_status(node,"unable to connect to node"); + inform_node_status(node, "unable to connect to node"); } } } @@ -853,25 +882,26 @@ check_pgpool_status_by_query(void) * Used in wd_lifecheck. */ static void * -thread_ping_pgpool(void * arg) +thread_ping_pgpool(void *arg) { - uintptr_t rtn; - WdPgpoolThreadArg * thread_arg = (WdPgpoolThreadArg *)arg; - rtn = (uintptr_t)wd_ping_pgpool(thread_arg->lifeCheckNode); + uintptr_t rtn; + WdPgpoolThreadArg *thread_arg = (WdPgpoolThreadArg *) arg; - pthread_exit((void *)rtn); + rtn = (uintptr_t) wd_ping_pgpool(thread_arg->lifeCheckNode); + + pthread_exit((void *) rtn); } /* * Create connection to pgpool */ static PGconn * -create_conn(char * hostname, int port) +create_conn(char *hostname, int port) { static char conninfo[1024]; - PGconn *conn; - char *password = get_pgpool_config_user_password(pool_config->wd_lifecheck_user, - pool_config->wd_lifecheck_password); + PGconn *conn; + char *password = get_pgpool_config_user_password(pool_config->wd_lifecheck_user, + pool_config->wd_lifecheck_password); if (strlen(pool_config->wd_lifecheck_dbname) == 0) @@ -888,14 +918,14 @@ create_conn(char * hostname, int port) return NULL; } - snprintf(conninfo,sizeof(conninfo), - "host='%s' port='%d' dbname='%s' user='%s' password='%s' connect_timeout='%d'", - hostname, - port, - pool_config->wd_lifecheck_dbname, - pool_config->wd_lifecheck_user, - password?password:"", - pool_config->wd_interval / 2 + 1); + snprintf(conninfo, sizeof(conninfo), + "host='%s' port='%d' dbname='%s' user='%s' password='%s' connect_timeout='%d'", + hostname, + port, + pool_config->wd_lifecheck_dbname, + pool_config->wd_lifecheck_user, + password ? password : "", + pool_config->wd_interval / 2 + 1); conn = PQconnectdb(conninfo); if (password) @@ -904,7 +934,7 @@ create_conn(char * hostname, int port) if (PQstatus(conn) != CONNECTION_OK) { ereport(DEBUG1, - (errmsg("watchdog life checking"), + (errmsg("watchdog life checking"), errdetail("Connection to database failed: %s", PQerrorMessage(conn)))); PQfinish(conn); return NULL; @@ -917,18 +947,18 @@ create_conn(char * hostname, int port) * Check if pgpool is alive using heartbeat signal. */ static int -wd_check_heartbeat(LifeCheckNode* node) +wd_check_heartbeat(LifeCheckNode * node) { - int interval; + int interval; struct timeval tv; if (!WD_TIME_ISSET(node->hb_last_recv_time) || - !WD_TIME_ISSET(node->hb_send_time)) + !WD_TIME_ISSET(node->hb_send_time)) { ereport(DEBUG1, - (errmsg("watchdog checking if pgpool is alive using heartbeat"), - errdetail("pgpool (%s:%d) was restarted and has not send the heartbeat signal yet", - node->hostName, node->pgpoolPort))); + (errmsg("watchdog checking if pgpool is alive using heartbeat"), + errdetail("pgpool (%s:%d) was restarted and has not send the heartbeat signal yet", + node->hostName, node->pgpoolPort))); return WD_OK; } @@ -936,9 +966,9 @@ wd_check_heartbeat(LifeCheckNode* node) interval = WD_TIME_DIFF_SEC(tv, node->hb_last_recv_time); ereport(DEBUG1, - (errmsg("watchdog checking if pgpool is alive using heartbeat"), - errdetail("the last heartbeat from \"%s:%d\" received %d seconds ago", - node->hostName, node->pgpoolPort, interval))); + (errmsg("watchdog checking if pgpool is alive using heartbeat"), + errdetail("the last heartbeat from \"%s:%d\" received %d seconds ago", + node->hostName, node->pgpoolPort, interval))); if (interval > pool_config->wd_heartbeat_deadtime) { @@ -948,7 +978,7 @@ wd_check_heartbeat(LifeCheckNode* node) if (node->nodeState == NODE_DEAD) { node->nodeState = NODE_ALIVE; - inform_node_status(node,"Heartbeat signal found"); + inform_node_status(node, "Heartbeat signal found"); } return WD_OK; } @@ -957,9 +987,9 @@ wd_check_heartbeat(LifeCheckNode* node) * Check if pgpool can accept the lifecheck query. */ static int -wd_ping_pgpool(LifeCheckNode* node) +wd_ping_pgpool(LifeCheckNode * node) { - PGconn * conn; + PGconn *conn; conn = create_conn(node->hostName, node->pgpoolPort); if (conn == NULL) @@ -969,18 +999,18 @@ wd_ping_pgpool(LifeCheckNode* node) /* inner function for issueing lifecheck query */ static int -ping_pgpool(PGconn * conn) +ping_pgpool(PGconn *conn) { - int rtn = WD_NG; - int status = PGRES_FATAL_ERROR; - PGresult * res = (PGresult *)NULL; + int rtn = WD_NG; + int status = PGRES_FATAL_ERROR; + PGresult *res = (PGresult *) NULL; if (!conn) { return WD_NG; } - res = PQexec(conn, pool_config->wd_lifecheck_query ); + res = PQexec(conn, pool_config->wd_lifecheck_query); status = PQresultStatus(res); if (res != NULL) @@ -988,8 +1018,8 @@ ping_pgpool(PGconn * conn) PQclear(res); } - if ((status != PGRES_NONFATAL_ERROR ) && - (status != PGRES_FATAL_ERROR )) + if ((status != PGRES_NONFATAL_ERROR) && + (status != PGRES_FATAL_ERROR)) { rtn = WD_OK; } @@ -1008,11 +1038,13 @@ is_parent_alive() } -static void wd_initialize_trusted_servers_list(void) +static void +wd_initialize_trusted_servers_list(void) { - char* token; - char* tmpString; - const char* delimi = ","; + char *token; + char *tmpString; + const char *delimi = ","; + if (g_trusted_server_list) return; @@ -1025,45 +1057,49 @@ static void wd_initialize_trusted_servers_list(void) tmpString = pstrdup(pool_config->trusted_servers); for (token = strtok(tmpString, delimi); token != NULL; token = strtok(NULL, delimi)) { - WdUpstreamConnectionData* server = palloc(sizeof(WdUpstreamConnectionData)); + WdUpstreamConnectionData *server = palloc(sizeof(WdUpstreamConnectionData)); + server->pid = 0; server->reachable = false; server->hostname = pstrdup(token); - g_trusted_server_list = lappend(g_trusted_server_list,server); + g_trusted_server_list = lappend(g_trusted_server_list, server); ereport(LOG, - (errmsg("watchdog lifecheck trusted server \"%s\" added for the availability check",token))); + (errmsg("watchdog lifecheck trusted server \"%s\" added for the availability check", token))); } pfree(tmpString); MemoryContextSwitchTo(oldCxt); } -static bool wd_ping_all_server(void) +static bool +wd_ping_all_server(void) { - ListCell *lc; - pid_t pid; - int status; - int ping_process = 0; + ListCell *lc; + pid_t pid; + int status; + int ping_process = 0; POOL_SETMASK(&BlockSig); foreach(lc, g_trusted_server_list) { - WdUpstreamConnectionData* server = (WdUpstreamConnectionData*)lfirst(lc); + WdUpstreamConnectionData *server = (WdUpstreamConnectionData *) lfirst(lc); + if (server->pid <= 0) - server->pid = wd_issue_ping_command(server->hostname,&server->outputfd); + server->pid = wd_issue_ping_command(server->hostname, &server->outputfd); if (server->pid > 0) ping_process++; } - while(ping_process > 0) + while (ping_process > 0) { pid = waitpid(0, &status, 0); if (pid > 0) { /* find the server object associated with this pid */ - WdUpstreamConnectionData* server = wd_get_server_from_pid(pid); + WdUpstreamConnectionData *server = wd_get_server_from_pid(pid); + if (server) { ping_process--; @@ -1080,15 +1116,15 @@ static bool wd_ping_all_server(void) else { /* It was not a ping host child process */ - wd_reaper_lifecheck(pid,status); + wd_reaper_lifecheck(pid, status); } } - if (pid == -1) /* wait pid error */ + if (pid == -1) /* wait pid error */ { if (errno == EINTR) continue; ereport(WARNING, - (errmsg("failed to check the ping status of trusted servers"), + (errmsg("failed to check the ping status of trusted servers"), errdetail("waitpid failed with reason: %s", strerror(errno)))); break; } @@ -1097,13 +1133,14 @@ static bool wd_ping_all_server(void) return false; } -static WdUpstreamConnectionData* wd_get_server_from_pid(pid_t pid) +static WdUpstreamConnectionData * wd_get_server_from_pid(pid_t pid) { - ListCell *lc; + ListCell *lc; foreach(lc, g_trusted_server_list) { - WdUpstreamConnectionData* server = (WdUpstreamConnectionData*)lfirst(lc); + WdUpstreamConnectionData *server = (WdUpstreamConnectionData *) lfirst(lc); + if (server->pid == pid) { return server; @@ -1111,5 +1148,3 @@ static WdUpstreamConnectionData* wd_get_server_from_pid(pid_t pid) } return NULL; } - - diff --git a/src/watchdog/wd_ping.c b/src/watchdog/wd_ping.c index 7bd210ba4..67e9ecbe4 100644 --- a/src/watchdog/wd_ping.c +++ b/src/watchdog/wd_ping.c @@ -37,35 +37,38 @@ #define WD_MAX_PING_RESULT 256 -static double get_result (char * ping_data); +static double get_result(char *ping_data); /** * check if IP address can be pinged. */ -bool wd_is_ip_exists(char* ip) +bool +wd_is_ip_exists(char *ip) { - pid_t pid; - int outputfd; - int status; + pid_t pid; + int outputfd; + int status; if (ip == NULL) return false; POOL_SETMASK(&AuthBlockSig); - pid = wd_issue_ping_command(ip,&outputfd); - if (pid <= 0) + pid = wd_issue_ping_command(ip, &outputfd); + if (pid <= 0) { POOL_SETMASK(&UnBlockSig); return false; } - for(;;) + for (;;) { - pid_t sts = waitpid(pid, &status, 0); + pid_t sts = waitpid(pid, &status, 0); + if (sts == pid) { - bool ret = wd_get_ping_result(ip, status, outputfd); + bool ret = wd_get_ping_result(ip, status, outputfd); + POOL_SETMASK(&UnBlockSig); close(outputfd); return ret; @@ -76,7 +79,7 @@ bool wd_is_ip_exists(char* ip) POOL_SETMASK(&UnBlockSig); close(outputfd); ereport(WARNING, - (errmsg("watchdog failed to ping host\"%s\"",ip), + (errmsg("watchdog failed to ping host\"%s\"", ip), errdetail("waitpid() failed with reason \"%s\"", strerror(errno)))); return false; } @@ -89,23 +92,25 @@ bool wd_is_ip_exists(char* ip) * function issues the ping command using the execv system call * and return the pid of the process. */ -pid_t wd_issue_ping_command(char* hostname, int* outfd) +pid_t +wd_issue_ping_command(char *hostname, int *outfd) { - int status; - char * args[8]; - int pid, i = 0; - int pfd[2]; - char ping_path[WD_MAX_PATH_LEN]; + int status; + char *args[8]; + int pid, + i = 0; + int pfd[2]; + char ping_path[WD_MAX_PATH_LEN]; - snprintf(ping_path,sizeof(ping_path),"%s/ping",pool_config->ping_path); + snprintf(ping_path, sizeof(ping_path), "%s/ping", pool_config->ping_path); ereport(DEBUG2, - (errmsg("watchdog trying to ping host \"%s\"",hostname))); + (errmsg("watchdog trying to ping host \"%s\"", hostname))); if (pipe(pfd) == -1) { ereport(WARNING, - (errmsg("watchdog failed to ping host\"%s\"",hostname), + (errmsg("watchdog failed to ping host\"%s\"", hostname), errdetail("pipe open failed. reason: %s", strerror(errno)))); return -1; } @@ -120,7 +125,7 @@ pid_t wd_issue_ping_command(char* hostname, int* outfd) if (pid == -1) { ereport(WARNING, - (errmsg("watchdog failed to ping host\"%s\"",hostname), + (errmsg("watchdog failed to ping host\"%s\"", hostname), errdetail("fork() failed. reason: %s", strerror(errno)))); return -1; } @@ -132,12 +137,12 @@ pid_t wd_issue_ping_command(char* hostname, int* outfd) close(STDOUT_FILENO); dup2(pfd[1], STDOUT_FILENO); close(pfd[0]); - status = execv(ping_path,args); + status = execv(ping_path, args); if (status == -1) { ereport(FATAL, - (errmsg("watchdog failed to ping host\"%s\"",hostname), + (errmsg("watchdog failed to ping host\"%s\"", hostname), errdetail("execv(%s) failed. reason: %s", ping_path, strerror(errno)))); } exit(0); @@ -151,44 +156,45 @@ pid_t wd_issue_ping_command(char* hostname, int* outfd) * The function is helper function and can be used with the * wd_issue_ping_command() function to identify if the ping command * was successful */ -bool wd_get_ping_result(char* hostname, int exit_status, int outfd) +bool +wd_get_ping_result(char *hostname, int exit_status, int outfd) { - /* First check the exit status of ping process*/ + /* First check the exit status of ping process */ if (WIFEXITED(exit_status) == 0) { ereport(WARNING, - (errmsg("watchdog failed to ping host\"%s\"",hostname), + (errmsg("watchdog failed to ping host\"%s\"", hostname), errdetail("ping process exited abnormally"))); } else if (WEXITSTATUS(exit_status) != 0) { ereport(WARNING, - (errmsg("watchdog failed to ping host\"%s\"",hostname), + (errmsg("watchdog failed to ping host\"%s\"", hostname), errdetail("ping process exits with code: %d", WEXITSTATUS(exit_status)))); } else { - char result[WD_MAX_PING_RESULT]; - int i = 0; - int r_size = 0; + char result[WD_MAX_PING_RESULT]; + int i = 0; + int r_size = 0; ereport(DEBUG1, (errmsg("watchdog ping process for host \"%s\" exited successfully", hostname))); - while (( (r_size = read (outfd, &result[i], sizeof(result)-i-1)) > 0) && (errno == EINTR)) + while (((r_size = read(outfd, &result[i], sizeof(result) - i - 1)) > 0) && (errno == EINTR)) { i += r_size; } - result[sizeof(result)-1] = '\0'; + result[sizeof(result) - 1] = '\0'; /* Check whether average RTT >= 0 */ - if (get_result (result) >= 0) + if (get_result(result) >= 0) { ereport(DEBUG1, (errmsg("watchdog succeeded to ping a host \"%s\"", hostname))); return true; } ereport(WARNING, - (errmsg("ping host\"%s\" failed",hostname), + (errmsg("ping host\"%s\" failed", hostname), errdetail("average RTT value is not greater than zero"))); } return false; @@ -198,12 +204,12 @@ bool wd_get_ping_result(char* hostname, int exit_status, int outfd) * Get average round-trip time of ping result. */ static double -get_result (char * ping_data) +get_result(char *ping_data) { - char * sp = NULL; - char * ep = NULL; - int i; - double msec = 0; + char *sp = NULL; + char *ep = NULL; + int i; + double msec = 0; if (ping_data == NULL) { @@ -212,26 +218,26 @@ get_result (char * ping_data) return -1; } ereport(DEBUG1, - (errmsg("watchdog ping"), + (errmsg("watchdog ping"), errdetail("ping data: %s", ping_data))); + /* - skip result until average data - typical result of ping is as follows, - "rtt min/avg/max/mdev = 0.045/0.045/0.046/0.006 ms" - we can find the average data beyond the 4th '/'. + * skip result until average data typical result of ping is as follows, + * "rtt min/avg/max/mdev = 0.045/0.045/0.046/0.006 ms" we can find the + * average data beyond the 4th '/'. */ sp = ping_data; - for ( i = 0 ; i < 4 ; i ++) + for (i = 0; i < 4; i++) { - sp = strchr(sp,'/'); + sp = strchr(sp, '/'); if (sp == NULL) { return -1; } - sp ++; + sp++; } - ep = strchr (sp,'/'); + ep = strchr(sp, '/'); if (ep == NULL) { return -1; @@ -241,7 +247,7 @@ get_result (char * ping_data) errno = 0; /* convert to numeric data from text */ - msec = strtod(sp,(char **)NULL); + msec = strtod(sp, (char **) NULL); if (errno != 0) { diff --git a/src/watchdog/wd_utils.c b/src/watchdog/wd_utils.c index 24e27b6ea..658024d5a 100644 --- a/src/watchdog/wd_utils.c +++ b/src/watchdog/wd_utils.c @@ -41,28 +41,31 @@ #include "watchdog/wd_utils.h" #include "utils/ssl_utils.h" -static int has_setuid_bit(char * path); +static int has_setuid_bit(char *path); static void *exec_func(void *arg); /* * thread information for pool_thread */ -typedef struct { - void *(*start_routine)(void *); - void *arg; -} WdThreadInfo; +typedef struct +{ + void *(*start_routine) (void *); + void *arg; +} WdThreadInfo; -void wd_check_network_command_configurations(void) +void +wd_check_network_command_configurations(void) { - char path[128]; - char* command; + char path[128]; + char *command; if (pool_config->use_watchdog == 0) return; + /* - * If delegate IP is not assigned to the node - * the configuration is not used + * If delegate IP is not assigned to the node the configuration is not + * used */ if (strlen(pool_config->delegate_IP) == 0) return; @@ -73,18 +76,18 @@ void wd_check_network_command_configurations(void) { snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); pfree(command); - if (! has_setuid_bit(path)) + if (!has_setuid_bit(path)) { ereport(WARNING, - (errmsg("checking setuid bit of if_up_cmd"), + (errmsg("checking setuid bit of if_up_cmd"), errdetail("ifup[%s] doesn't have setuid bit", path))); } } else { ereport(FATAL, - (errmsg("invalid configuration for if_up_cmd parameter"), - errdetail("unable to get command from \"%s\"",pool_config->if_up_cmd))); + (errmsg("invalid configuration for if_up_cmd parameter"), + errdetail("unable to get command from \"%s\"", pool_config->if_up_cmd))); } /* check setuid bit of ifdown command */ @@ -93,18 +96,18 @@ void wd_check_network_command_configurations(void) { snprintf(path, sizeof(path), "%s/%s", pool_config->if_cmd_path, command); pfree(command); - if (! has_setuid_bit(path)) + if (!has_setuid_bit(path)) { ereport(WARNING, - (errmsg("checking setuid bit of if_down_cmd"), + (errmsg("checking setuid bit of if_down_cmd"), errdetail("ifdown[%s] doesn't have setuid bit", path))); } } else { ereport(FATAL, - (errmsg("invalid configuration for if_down_cmd parameter"), - errdetail("unable to get command from \"%s\"",pool_config->if_down_cmd))); + (errmsg("invalid configuration for if_down_cmd parameter"), + errdetail("unable to get command from \"%s\"", pool_config->if_down_cmd))); } /* check setuid bit of arping command */ @@ -113,18 +116,18 @@ void wd_check_network_command_configurations(void) { snprintf(path, sizeof(path), "%s/%s", pool_config->arping_path, command); pfree(command); - if (! has_setuid_bit(path)) + if (!has_setuid_bit(path)) { ereport(WARNING, - (errmsg("checking setuid bit of arping command"), + (errmsg("checking setuid bit of arping command"), errdetail("arping[%s] doesn't have setuid bit", path))); } } else { ereport(FATAL, - (errmsg("invalid configuration for arping_cmd parameter"), - errdetail("unable to get command from \"%s\"",pool_config->arping_cmd))); + (errmsg("invalid configuration for arping_cmd parameter"), + errdetail("unable to get command from \"%s\"", pool_config->arping_cmd))); } } @@ -133,16 +136,17 @@ void wd_check_network_command_configurations(void) * if the file has setuid bit and the owner is root, it returns 1, otherwise returns 0 */ static int -has_setuid_bit(char * path) +has_setuid_bit(char *path) { struct stat buf; - if (stat(path,&buf) < 0) + + if (stat(path, &buf) < 0) { ereport(FATAL, - (return_code(1), + (return_code(1), errmsg("has_setuid_bit: command '%s' not found", path))); } - return ((buf.st_uid == 0) && (S_ISREG(buf.st_mode)) && (buf.st_mode & S_ISUID))?1:0; + return ((buf.st_uid == 0) && (S_ISREG(buf.st_mode)) && (buf.st_mode & S_ISUID)) ? 1 : 0; } @@ -159,12 +163,13 @@ wd_calc_hash(const char *str, int len, char *buf) void wd_calc_hash(const char *str, int len, char *buf) { - char pass[(MAX_PASSWORD_SIZE + 1) / 2]; - char username[(MAX_PASSWORD_SIZE + 1) / 2]; - size_t pass_len; - size_t username_len; - size_t authkey_len; - char tmp_buf[(MD5_PASSWD_LEN+1)*2]; + char pass[(MAX_PASSWORD_SIZE + 1) / 2]; + char username[(MAX_PASSWORD_SIZE + 1) / 2]; + size_t pass_len; + size_t username_len; + size_t authkey_len; + char tmp_buf[(MD5_PASSWD_LEN + 1) * 2]; + /* use first half of authkey as username, last half as password */ authkey_len = strlen(pool_config->wd_authkey); @@ -173,17 +178,17 @@ wd_calc_hash(const char *str, int len, char *buf) username_len = authkey_len / 2; pass_len = authkey_len - username_len; - if ( snprintf(username, username_len + 1, "%s", pool_config->wd_authkey) < 0 + if (snprintf(username, username_len + 1, "%s", pool_config->wd_authkey) < 0 || snprintf(pass, pass_len + 1, "%s", pool_config->wd_authkey + username_len) < 0) goto wd_calc_hash_error; /* calculate hash using md5 encrypt */ - if (! pool_md5_encrypt(pass, username, strlen(username), tmp_buf + MD5_PASSWD_LEN + 1)) + if (!pool_md5_encrypt(pass, username, strlen(username), tmp_buf + MD5_PASSWD_LEN + 1)) goto wd_calc_hash_error; - tmp_buf[sizeof(tmp_buf)-1] = '\0'; + tmp_buf[sizeof(tmp_buf) - 1] = '\0'; - if (! pool_md5_encrypt(tmp_buf+MD5_PASSWD_LEN+1, str, len, tmp_buf)) + if (!pool_md5_encrypt(tmp_buf + MD5_PASSWD_LEN + 1, str, len, tmp_buf)) goto wd_calc_hash_error; memcpy(buf, tmp_buf, MD5_PASSWD_LEN); @@ -205,31 +210,32 @@ wd_calc_hash_error: char * string_replace(const char *string, const char *pattern, const char *replacement) { - char *tok = NULL; - char *newstr = NULL; - char *oldstr = NULL; - char *head = NULL; - size_t pat_len,rep_len; - + char *tok = NULL; + char *newstr = NULL; + char *oldstr = NULL; + char *head = NULL; + size_t pat_len, + rep_len; + newstr = pstrdup(string); /* bail out if no pattern or replacement is given */ - if ( pattern == NULL || replacement == NULL ) + if (pattern == NULL || replacement == NULL) return newstr; - + pat_len = strlen(pattern); rep_len = strlen(replacement); - + head = newstr; - while ( (tok = strstr(head,pattern))) + while ((tok = strstr(head, pattern))) { oldstr = newstr; - newstr = palloc ( strlen ( oldstr ) - pat_len + rep_len + 1 ); - - memcpy(newstr, oldstr, tok - oldstr ); - memcpy(newstr + (tok - oldstr), replacement, rep_len ); + newstr = palloc(strlen(oldstr) - pat_len + rep_len + 1); + + memcpy(newstr, oldstr, tok - oldstr); + memcpy(newstr + (tok - oldstr), replacement, rep_len); memcpy(newstr + (tok - oldstr) + rep_len, tok + pat_len, strlen(oldstr) - pat_len - (tok - oldstr)); /* put the string terminator */ - memset( newstr + strlen (oldstr) - pat_len + rep_len , 0, 1 ); + memset(newstr + strlen(oldstr) - pat_len + rep_len, 0, 1); /* move back head right after the last replacement */ head = newstr + (tok - oldstr) + rep_len; pfree(oldstr); @@ -240,9 +246,10 @@ string_replace(const char *string, const char *pattern, const char *replacement) /* * The function is wrapper over pthread_create. */ -int watchdog_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) +int watchdog_thread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) { - WdThreadInfo* thread_arg = palloc(sizeof(WdThreadInfo)); + WdThreadInfo *thread_arg = palloc(sizeof(WdThreadInfo)); + thread_arg->arg = arg; thread_arg->start_routine = start_routine; return pthread_create(thread, attr, exec_func, thread_arg); @@ -251,8 +258,8 @@ int watchdog_thread_create(pthread_t *thread, const pthread_attr_t *attr, void * static void * exec_func(void *arg) { - WdThreadInfo* thread_arg = (WdThreadInfo*) arg; + WdThreadInfo *thread_arg = (WdThreadInfo *) arg; + Assert(thread_arg != NULL); return thread_arg->start_routine(thread_arg->arg); } - [parent: d494c63eb7bf]