pgpool2.git / summary / log / commit / refs
commit 3cbce4eaf870e89fdd8f8a2ad8fab8d3d8aadf65
Author: Tatsuo Ishii <ishii@postgresql.org>
Date: Wed Jul 27 05:28:28 2016 +0000
Replace "MAJOR" macro to prevent occasional failure.
It is reported that the macro could cause segfault
[http://www.pgpool.net/mantisbt/view.php?id=225]. The macro calls
pool_virtual_master_db_node_id() and then access
backend->slots[id]->con using the node id returned. In rare cases, it
could point to 0 (in case when the DB node is not connected), which
gives access to con->major, then it causes a segfault.
Since the intention of the macro is obtaining the protocol major
number, it is a little bit pointless to keep the info on the data for
each DB node because the number should be identical among DB
nodes. To fix this, now we have the protocol major and minor version
numbers in the session context and they are set when pgpool-II
connects to backend. The setter and getter functions are added .The
macro now just returns the stored data by using the getter function
(this will save a few cpu cycle).
src/context/pool_session_context.c | 46 ++++++++++++++++++++++
src/include/context/pool_session_context.h | 9 +++++
src/include/pool.h | 2 +-
src/protocol/child.c | 6 +++
src/rewrite/pool_timestamp.c | 4 +-
.../tests/010.rewrite_timestamp/timestamp/main.c | 5 +++
6 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/src/context/pool_session_context.c b/src/context/pool_session_context.c
index 20ae9e60d..10608679d 100644
--- a/src/context/pool_session_context.c
+++ b/src/context/pool_session_context.c
@@ -1206,3 +1206,49 @@ static POOL_PENDING_MESSAGE *copy_pending_message(POOL_PENDING_MESSAGE *message)
return msg;
}
+
+/*
+ * Set protocol major version number
+ */
+void pool_set_major_version(int major)
+{
+ if (session_context)
+ {
+ session_context->major = major;
+ }
+}
+
+/*
+ * Get protocol major version number
+ */
+int pool_get_major_version(void)
+{
+ if (session_context)
+ {
+ return session_context->major;
+ }
+ return PROTO_MAJOR_V3;
+}
+
+/*
+ * Set protocol minor version number
+ */
+void pool_set_minor_version(int minor)
+{
+ if (session_context)
+ {
+ session_context->minor = minor;
+ }
+}
+
+/*
+ * Get protocol minor version number
+ */
+int pool_get_minor_version(void)
+{
+ if (session_context)
+ {
+ return session_context->minor;
+ }
+ return 0;
+}
diff --git a/src/include/context/pool_session_context.h b/src/include/context/pool_session_context.h
index 5a4486540..2be0c205a 100644
--- a/src/include/context/pool_session_context.h
+++ b/src/include/context/pool_session_context.h
@@ -210,6 +210,11 @@ typedef struct {
* Parse/Bind/Close message queue.
*/
List *pending_messages;
+
+ /* Protocol major version number */
+ int major;
+ /* Protocol minor version number */
+ int minor;
} POOL_SESSION_CONTEXT;
extern void pool_init_session_context(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend);
@@ -266,6 +271,10 @@ extern void pool_pending_message_add(POOL_PENDING_MESSAGE* message);
extern POOL_PENDING_MESSAGE *pool_pending_message_remove(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_set_major_version(int major);
+extern int pool_get_major_version(void);
+extern void pool_set_minor_version(int minor);
+extern int pool_get_minor_version(void);
#ifdef NOT_USED
extern void pool_add_prep_where(char *name, bool *map);
diff --git a/src/include/pool.h b/src/include/pool.h
index 1f43efd08..7ae888181 100644
--- a/src/include/pool.h
+++ b/src/include/pool.h
@@ -347,7 +347,7 @@ extern int my_master_node_id;
#define SLONY (MASTER_SLAVE && pool_config->master_slave_sub_mode == SLONY_MODE)
#define DUAL_MODE (REPLICATION || MASTER_SLAVE)
#define RAW_MODE (!REPLICATION && !MASTER_SLAVE)
-#define MAJOR(p) MASTER_CONNECTION(p)->sp->major
+#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)
diff --git a/src/protocol/child.c b/src/protocol/child.c
index 4f6b3c29f..7ad142a0d 100644
--- a/src/protocol/child.c
+++ b/src/protocol/child.c
@@ -349,6 +349,12 @@ void do_child(int *fds)
*/
pool_init_session_context(child_frontend, backend);
+ /*
+ * Set protocol versions
+ */
+ pool_set_major_version(sp->major);
+ pool_set_minor_version(sp->minor);
+
/*
* Mark this connection pool is connected from frontend
*/
diff --git a/src/rewrite/pool_timestamp.c b/src/rewrite/pool_timestamp.c
index 6f6bbfd37..8115bbf6e 100644
--- a/src/rewrite/pool_timestamp.c
+++ b/src/rewrite/pool_timestamp.c
@@ -5,7 +5,7 @@
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
*
- * Copyright (c) 2003-2015 PgPool Global Development Group
+ * Copyright (c) 2003-2016 PgPool Global Development Group
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby
@@ -32,6 +32,8 @@
#include "parser/parsenodes.h"
#include "parser/parser.h"
#include "utils/palloc.h"
+#include "utils/memutils.h"
+#include "context/pool_session_context.h"
typedef struct {
char *attrname; /* attribute name */
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 1960d7962..e62060fc9 100644
--- a/src/test/regression/tests/010.rewrite_timestamp/timestamp/main.c
+++ b/src/test/regression/tests/010.rewrite_timestamp/timestamp/main.c
@@ -61,6 +61,11 @@ char *remove_quotes_and_schema_from_relname(char *table)
return table;
}
+int pool_get_major_version(void)
+{
+ return PROTO_MAJOR_V3;
+}
+
POOL_RELCACHE *
pool_create_relcache(int cachesize, char *sql, func_ptr register_func, func_ptr unregister_func, bool issessionlocal)
{
[parent: 58cf6391b98c]