pgpool2.git / summary / log / commit / refs

commit    1244817ebd4b3728e441a0feb81d8074c2605ef9
Author:   Muhammad Usama <m.usama@gmail.com>
Date:     Wed Jan 06 19:09:57 2016 +0000

    pcp_watchdof_info utility enhancement
    
    pcp_watchdog_info only gives the information of a single watchdog node which
    might not be enough in some certain situations. And as we are currently in the
    process of enhancing watchdog system so pcp_watchdog_info utility is also
    getting its share of enhancements. The commit adds a little more information
    about the watchdog cluster state and nodes in the output of pcp_watchdog_info.


doc/pgpool-en.html | 100 ++++++++++++++---- src/include/pcp/pcp.h | 13 +++ src/include/watchdog/wd_json_data.h | 2 + src/libs/pcp/Makefile.am | 5 + src/libs/pcp/Makefile.in | 32 +++++- src/libs/pcp/pcp.c | 195 ++++++++++++++++++++++++++++++------ src/pcp_con/pcp_worker.c | 65 ++++-------- src/tools/pcp/pcp_frontend_client.c | 68 ++++++++++--- src/utils/json.c | 11 +- src/utils/pcp/pcp_stream.c | 2 +- src/watchdog/watchdog.c | 33 +++--- src/watchdog/wd_json_data.c | 30 ++++-- 12 files changed, 418 insertions(+), 138 deletions(-) diff --git a/doc/pgpool-en.html b/doc/pgpool-en.html index 7190a44be..926f9bb5a 100644 --- a/doc/pgpool-en.html +++ b/doc/pgpool-en.html @@ -4907,9 +4907,18 @@ Weight : 0.5 </dd> <dt>Description:</dt> <dd> - <p>Displays the watchdog status of the pgpool-II. - <code>watchdog_id</code> is the index of other_pgpool_hostname parameter in pgpool.conf. - If this is omitted, display the watchdog status of local pgpool-II.</p> +<p>Displays the watchdog status of the pgpool-II. +<code>watchdog_id</code> is the index of watchdog node to get information for. +If this is omitted, display the watchdog status of all watchdog nodes in the cluster. +</p><p> +<code>watchdog_id</code> = 0 is reserved for current pgpool-II node, +So the index of remote watchdog nodes starts from 1. +Note that since the index numbering in pcp_watchdog_info utility starts from 1 while +the pgpool.conf file uses 0 based indexing to define remote watchdog nodes, so you will require +to add one to the other watchdog index to get its information using pcp_watchdog_info utility. +</p><p> +For example, to get the information of first remote watchdog node configured with prefix 0 +defined by other_pgpool_hostname0 parameters you will use watchdog_id = 1 for pcp_watchdog_info.</p> </dd> <dt>Options:</dt> <dd> @@ -4917,7 +4926,8 @@ Weight : 0.5 <dt><code>-n <strong>watchdog_id</strong>, --node-id=<strong>watchdog_id</strong></code></dt> <dd> <p>The index of other pgpool-II to get information for.</p> - <p>If ommitted then gets one's self watchdog information'.</p> + <p>Index 0 gets one's self watchdog information'.</p> + <p>If ommitted then gets information of all watchdog nodes'.</p> </dd> <dt>Other options</dt> <dd> @@ -4928,30 +4938,84 @@ Weight : 0.5 <dt>Output example:</dt> <dd> <pre> -$ pcp_watchdog_info -h localhost -p 9898 -u postgres 0 +$ pcp_watchdog_info -h localhost -u postgres + +3 NO Linux_host1.localdomain_9991 host1 + +Linux_host1.localdomain_9991 host1 9991 9001 7 STANDBY +Linux_host2.localdomain_9992 host2 9992 9002 4 MASTER +Linux_host3.localdomain_9993 host3 9993 9003 7 STANDBY -host1 9999 9000 2 -Here is an output example: </pre> <p>The result is in the following order:</p> +<p>The first output line describes the watchdog cluster information:</p> <ol> -<li>hostname</li> -<li>port number for pgpool-II</li> -<li>port number for watchdog</li> -<li>watchdog Status</li> +<li>Total watchdog nodes in the cluster</li> +<li>Is VIP is up on current node?</li> +<li>Master node name</li> +<li>Master node host</li> </ol> -<p>Status is represented by a digit from [1 to 4].</p> -<ul> -<li>1 - watchdog is not started</li> -<li>2 - Standby: not holding the virtual IP</li> -<li>3 - Active: holding the virtual IP</li> -<li>4 - Down</li> -</ul> + +<p>Next is the list of watchdog nodes:</p> +<ol> + <li>node name</li> + <li>hostname</li> + <li>pgpool port</li> + <li>watchdog port</li> + <li>current node state</li> + <li>current node name</li> +</ol> +</dd> + +<dt>verbose mode:</dt> +<dd> +<pre> +$ pcp_watchdog_info -h localhost -v -u postgres + +Watchdog Cluster Information +Total Nodes : 3 +Remote Nodes : 2 +Quorum state : QUORUM EXIST +Alive Remote Nodes : 2 +VIP up on local node : NO +Master Node Name : Linux_host2.localdomain_9992 +Master Host Name : localhost + +Watchdog Node Information +Node Name : Linux_host1.localdomain_9991 +Host Name : host1 +Delegate IP : 192.168.1.10 +Pgpool port : 9991 +Watchdog port : 9001 +Node priority : 1 +status : 7 +status Name : STANDBY + +Node Name : Linux_host2.localdomain_9992 +Host Name : host2 +Delegate IP : 192.168.1.10 +Pgpool port : 9992 +Watchdog port : 9002 +Node priority : 1 +status : 4 +status Name : MASTER + +Node Name : Linux_host3.localdomain_9993 +Host Name : host3 +Delegate IP : 192.168.1.10 +Pgpool port : 9993 +Watchdog port : 9003 +Node priority : 1 +status : 7 +status Name : STANDBY + +</pre> </dd> </dl> + <h3 id="pcp_proc_count">pcp_proc_count</h3> <dl> <dt>Format:</dt> diff --git a/src/include/pcp/pcp.h b/src/include/pcp/pcp.h index e00a7e82a..0ebe55e11 100644 --- a/src/include/pcp/pcp.h +++ b/src/include/pcp/pcp.h @@ -34,6 +34,7 @@ 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 */ @@ -41,6 +42,18 @@ typedef struct PCPWDNodeInfo 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; + PCPWDNodeInfo nodeList[1]; +}PCPWDClusterInfo; + /* -------------------------------- * pcp.c * -------------------------------- diff --git a/src/include/watchdog/wd_json_data.h b/src/include/watchdog/wd_json_data.h index 940f41635..b3b09b807 100644 --- a/src/include/watchdog/wd_json_data.h +++ b/src/include/watchdog/wd_json_data.h @@ -33,8 +33,10 @@ 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; diff --git a/src/libs/pcp/Makefile.am b/src/libs/pcp/Makefile.am index e4be93088..a85b498ed 100644 --- a/src/libs/pcp/Makefile.am +++ b/src/libs/pcp/Makefile.am @@ -5,7 +5,10 @@ libpcp_la_LDFLAGS = -version-info 1:0:0 libpcp_la_SOURCES = pcp.c \ pcp_stream.c \ md5.c \ + json.c \ ../../utils/pool_path.c \ + ../../tools/fe_port.c \ + ../../tools/fe_memutils.c \ ../../utils/strlcpy.c include_HEADERS = ../../../src/include/pcp/pcp.h \ @@ -21,3 +24,5 @@ pcp_stream.c: ../../../src/utils/pcp/pcp_stream.c rm -f $@ && ln -s $< . strlcpy.c: ../../../src/utils/strlcpy.c rm -f $@ && ln -s $< . +json.c: ../../../src/utils/json.c + rm -f $@ && ln -s $< . diff --git a/src/libs/pcp/Makefile.in b/src/libs/pcp/Makefile.in index 8dcf8ced9..8ec51fde5 100644 --- a/src/libs/pcp/Makefile.in +++ b/src/libs/pcp/Makefile.in @@ -128,8 +128,9 @@ am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libpcp_la_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp -am_libpcp_la_OBJECTS = pcp.lo pcp_stream.lo md5.lo \ - ../../utils/pool_path.lo ../../utils/strlcpy.lo +am_libpcp_la_OBJECTS = pcp.lo pcp_stream.lo md5.lo json.lo \ + ../../utils/pool_path.lo ../../tools/fe_port.lo \ + ../../tools/fe_memutils.lo ../../utils/strlcpy.lo libpcp_la_OBJECTS = $(am_libpcp_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -333,7 +334,10 @@ libpcp_la_LDFLAGS = -version-info 1:0:0 libpcp_la_SOURCES = pcp.c \ pcp_stream.c \ md5.c \ + json.c \ ../../utils/pool_path.c \ + ../../tools/fe_port.c \ + ../../tools/fe_memutils.c \ ../../utils/strlcpy.c include_HEADERS = ../../../src/include/pcp/pcp.h \ @@ -418,6 +422,16 @@ clean-libLTLIBRARIES: @: > ../../utils/$(DEPDIR)/$(am__dirstamp) ../../utils/pool_path.lo: ../../utils/$(am__dirstamp) \ ../../utils/$(DEPDIR)/$(am__dirstamp) +../../tools/$(am__dirstamp): + @$(MKDIR_P) ../../tools + @: > ../../tools/$(am__dirstamp) +../../tools/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ../../tools/$(DEPDIR) + @: > ../../tools/$(DEPDIR)/$(am__dirstamp) +../../tools/fe_port.lo: ../../tools/$(am__dirstamp) \ + ../../tools/$(DEPDIR)/$(am__dirstamp) +../../tools/fe_memutils.lo: ../../tools/$(am__dirstamp) \ + ../../tools/$(DEPDIR)/$(am__dirstamp) ../../utils/strlcpy.lo: ../../utils/$(am__dirstamp) \ ../../utils/$(DEPDIR)/$(am__dirstamp) @@ -426,14 +440,19 @@ libpcp.la: $(libpcp_la_OBJECTS) $(libpcp_la_DEPENDENCIES) $(EXTRA_libpcp_la_DEPE mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f ../../tools/*.$(OBJEXT) + -rm -f ../../tools/*.lo -rm -f ../../utils/*.$(OBJEXT) -rm -f ../../utils/*.lo distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@../../tools/$(DEPDIR)/fe_memutils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@../../tools/$(DEPDIR)/fe_port.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../utils/$(DEPDIR)/pool_path.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../../utils/$(DEPDIR)/strlcpy.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/json.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_stream.Plo@am__quote@ @@ -467,6 +486,7 @@ mostlyclean-libtool: clean-libtool: -rm -rf .libs _libs + -rm -rf ../../tools/.libs ../../tools/_libs -rm -rf ../../utils/.libs ../../utils/_libs install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) @@ -605,6 +625,8 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../../tools/$(DEPDIR)/$(am__dirstamp) + -rm -f ../../tools/$(am__dirstamp) -rm -f ../../utils/$(DEPDIR)/$(am__dirstamp) -rm -f ../../utils/$(am__dirstamp) @@ -617,7 +639,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am - -rm -rf ../../utils/$(DEPDIR) ./$(DEPDIR) + -rm -rf ../../tools/$(DEPDIR) ../../utils/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -663,7 +685,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ../../utils/$(DEPDIR) ./$(DEPDIR) + -rm -rf ../../tools/$(DEPDIR) ../../utils/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -709,6 +731,8 @@ pcp_stream.c: ../../../src/utils/pcp/pcp_stream.c rm -f $@ && ln -s $< . strlcpy.c: ../../../src/utils/strlcpy.c rm -f $@ && ln -s $< . +json.c: ../../../src/utils/json.c + rm -f $@ && ln -s $< . # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. diff --git a/src/libs/pcp/pcp.c b/src/libs/pcp/pcp.c index c0c2b9811..3a6d1d975 100644 --- a/src/libs/pcp/pcp.c +++ b/src/libs/pcp/pcp.c @@ -44,6 +44,7 @@ #include "utils/pool_path.h" #include "utils/palloc.h" #include "utils/pool_process_reporting.h" +#include "utils/json.h" #include "auth/md5.h" #define PCPPASSFILE ".pcppass" @@ -1280,65 +1281,197 @@ _pcp_promote_node(PCPConnInfo* pcpConn,int nid, bool gracefully) static void process_watchdog_info_response(PCPConnInfo* pcpConn, char* buf, int len) { - PCPWDNodeInfo* watchdog_info = NULL; + char *json_data = NULL; + PCPWDClusterInfo* wd_cluster_info = NULL; + int clusterDataSize = 0; if (strcmp(buf, "CommandComplete") == 0) { - char *index = NULL; + int tempVal; + char* ptr; + json_data = (char *) memchr(buf, '\0', len); + if(json_data == NULL) + goto INVALID_RESPONSE; + json_data +=1; - watchdog_info = palloc(sizeof(PCPWDNodeInfo)); + json_value* root; + json_value* value; + int i,nodeCount; - index = (char *) memchr(buf, '\0', len); - if(index == NULL) + root = json_parse(json_data,len); + + /* The root node must be object */ + if (root == NULL || root->type != json_object) + { + json_value_free(root); goto INVALID_RESPONSE; - index +=1; - strlcpy(watchdog_info->hostName, index, sizeof(watchdog_info->hostName)-1); + } - index = (char *) memchr(buf, '\0', len); - if(index == NULL) + if (json_get_int_value_for_key(root, "NodeCount", &nodeCount)) + { + json_value_free(root); goto INVALID_RESPONSE; - index +=1; - strlcpy(watchdog_info->nodeName, index, sizeof(watchdog_info->nodeName) -1 ); + } - index = (char *) memchr(index, '\0', len); - if(index == NULL) + /* find the WatchdogNodes array */ + value = json_get_value_for_key(root,"WatchdogNodes"); + if (value == NULL) + { + json_value_free(root); goto INVALID_RESPONSE; - index +=1; - watchdog_info->pgpool_port = atoi(index); + } + if (value->type != json_array) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + if (nodeCount != value->u.array.length) + { + json_value_free(root); + goto INVALID_RESPONSE; + } - index = (char *) memchr(index, '\0', len); - if(index == NULL) + /* create the cluster object */ + clusterDataSize = sizeof(PCPWDClusterInfo) + (sizeof(PCPWDNodeInfo) * nodeCount); + wd_cluster_info = malloc(clusterDataSize); + + wd_cluster_info->nodeCount = nodeCount; + + if (json_get_int_value_for_key(root, "RemoteNodeCount", &wd_cluster_info->remoteNodeCount)) + { + json_value_free(root); goto INVALID_RESPONSE; - index +=1; - watchdog_info->wd_port = atoi(index); + } + if (json_get_int_value_for_key(root, "QuorumStatus", &wd_cluster_info->quorumStatus)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + if (json_get_int_value_for_key(root, "AliveNodeCount", &wd_cluster_info->aliveNodeCount)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + if (json_get_int_value_for_key(root, "Escalated", &tempVal)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + wd_cluster_info->escalated = tempVal==0?false:true; - index = (char *) memchr(index, '\0', len); - if(index == NULL) + ptr = json_get_string_value_for_key(root, "MasterNodeName"); + if (ptr == NULL) + { + json_value_free(root); goto INVALID_RESPONSE; - index +=1; - watchdog_info->state = atof(index); + } + strncpy(wd_cluster_info->masterNodeName, ptr, sizeof(wd_cluster_info->masterNodeName) -1); - if (setNextResultBinaryData(pcpConn->pcpResInfo, (void *)watchdog_info,sizeof(PCPWDNodeInfo) , NULL) < 0) + ptr = json_get_string_value_for_key(root, "MasterHostName"); + if (ptr == NULL) + { + json_value_free(root); goto INVALID_RESPONSE; + } + 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]; + + if (nodeInfoValue->type != json_object) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + + if (json_get_int_value_for_key(nodeInfoValue, "ID", &wdNodeInfo->id)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + + ptr = json_get_string_value_for_key(nodeInfoValue, "NodeName"); + if (ptr == NULL) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) -1); + + ptr = json_get_string_value_for_key(nodeInfoValue, "HostName"); + if (ptr == NULL) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) -1); + + ptr = json_get_string_value_for_key(nodeInfoValue, "DelegateIP"); + if (ptr == NULL) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) -1); + + if (json_get_int_value_for_key(nodeInfoValue, "WdPort", &wdNodeInfo->wd_port)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + + if (json_get_int_value_for_key(nodeInfoValue, "PgpoolPort", &wdNodeInfo->pgpool_port)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + + if (json_get_int_value_for_key(nodeInfoValue, "State", &wdNodeInfo->state)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + + ptr = json_get_string_value_for_key(nodeInfoValue, "StateName"); + if (ptr == NULL) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) -1); + + if (json_get_int_value_for_key(nodeInfoValue, "Priority", &wdNodeInfo->wd_priority)) + { + json_value_free(root); + goto INVALID_RESPONSE; + } + + } + json_value_free(root); + 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\"",buf); + "command failed with reason: \"%s\"\n",buf); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); } - return; INVALID_RESPONSE: - - if(watchdog_info) - pfree(watchdog_info); + + if(wd_cluster_info) + pfree(wd_cluster_info); pcp_internal_error(pcpConn, - "command failed. invalid response"); + "command failed. invalid response\n"); setResultStatus(pcpConn, PCP_RES_BAD_RESPONSE); - } /* -------------------------------- diff --git a/src/pcp_con/pcp_worker.c b/src/pcp_con/pcp_worker.c index 805591be2..8851c2960 100644 --- a/src/pcp_con/pcp_worker.c +++ b/src/pcp_con/pcp_worker.c @@ -757,16 +757,11 @@ static void inform_watchdog_info(PCP_CONNECTION *frontend,char *buf) { int wd_index; + int json_data_len; int wsize; char code[] = "CommandComplete"; - char pgpool_port_str[6]; - char wd_port_str[6]; - char status[2]; - json_value* root; - json_value* value; char* json_data; - WDNodeInfo *nodeInfo; - + if (!pool_config->use_watchdog) ereport(ERROR, (errmsg("PCP: informing watchdog info failed"), @@ -777,57 +772,31 @@ 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"), - errdetail("retrieved node information from shared memory"))); - - root = json_parse(json_data,strlen(json_data)); - - /* The root node must be object */ - if (root == NULL || root->type != json_object) - { - if(root) - json_value_free(root); - ereport(ERROR, - (errmsg("unable to parse json data for watchdog node info"))); - } - - value = json_get_value_for_key(root,"WatchdogNode"); - if (value == NULL || root->type != json_object) - { - json_value_free(root); - ereport(ERROR, - (errmsg("unable to parse json data for watchdog node info"))); - } - - nodeInfo = get_WDNodeInfo_from_wd_node_json(value); - json_value_free(root); + (errmsg("PCP: informing watchdog info"), + errdetail("retrieved node information from IPC socket"))); - snprintf(pgpool_port_str, sizeof(pgpool_port_str), "%d", nodeInfo->pgpool_port); - snprintf(wd_port_str, sizeof(wd_port_str), "%d", nodeInfo->wd_port); - snprintf(status, sizeof(status), "%d", nodeInfo->state); - - pcp_write(frontend, "w", 1); + /* + * 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) + - strlen(nodeInfo->hostName)+1 + - strlen(nodeInfo->nodeName)+1 + - strlen(pgpool_port_str)+1 + - strlen(wd_port_str)+1 + - strlen(status)+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, nodeInfo->hostName, strlen(nodeInfo->hostName)+1); - pcp_write(frontend, nodeInfo->nodeName, strlen(nodeInfo->nodeName)+1); - pcp_write(frontend, pgpool_port_str, strlen(pgpool_port_str)+1); - pcp_write(frontend, wd_port_str, strlen(wd_port_str)+1); - pcp_write(frontend, status, strlen(status)+1); + pcp_write(frontend, json_data, json_data_len +1); do_pcp_flush(frontend); - pfree(nodeInfo); + + pfree(json_data); } static void diff --git a/src/tools/pcp/pcp_frontend_client.c b/src/tools/pcp/pcp_frontend_client.c index 018c80bfc..67ca8b6e7 100644 --- a/src/tools/pcp/pcp_frontend_client.c +++ b/src/tools/pcp/pcp_frontend_client.c @@ -317,7 +317,7 @@ main(int argc, char **argv) } else if (current_app_type->app_type == PCP_WATCHDOG_INFO) { - nodeID = 0; + nodeID = -1; } } @@ -611,23 +611,62 @@ output_procinfo_result(PCPResultInfo* pcpResInfo, bool all, bool verbose) static void output_watchdog_info_result(PCPResultInfo* pcpResInfo, bool verbose) { - PCPWDNodeInfo *watchdog_info = (PCPWDNodeInfo *)pcp_get_binary_data(pcpResInfo,0); + int i; + PCPWDClusterInfo *cluster = (PCPWDClusterInfo *)pcp_get_binary_data(pcpResInfo,0); if (verbose) { - printf("NodeName : %s\n",watchdog_info->nodeName); - printf("HostName : %s\n",watchdog_info->hostName); - 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\n",watchdog_info->state); + char* quorumStatus; + if (cluster->quorumStatus == 0) + quorumStatus = "QUORUM IS ON THE EDGE"; + else if (cluster->quorumStatus == 1) + quorumStatus = "QUORUM EXIST"; + else if (cluster->quorumStatus == -1) + quorumStatus = "QUORUM ABSENT"; + else + 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("Watchdog Node Information \n"); + 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); + } } else { - printf("%s %d %d %d\n", - watchdog_info->hostName, - watchdog_info->pgpool_port, - watchdog_info->wd_port, - watchdog_info->state); + printf("%d %s %s %s\n\n", + cluster->remoteNodeCount +1, + cluster->escalated?"YES":"NO", + cluster->masterNodeName, + cluster->masterHostName); + + for (i=0; i< cluster->nodeCount; i++) + { + PCPWDNodeInfo* watchdog_info = &cluster->nodeList[i]; + printf("%s %s %d %d %d %s\n", + watchdog_info->nodeName, + watchdog_info->hostName, + watchdog_info->pgpool_port, + watchdog_info->wd_port, + watchdog_info->state, + watchdog_info->stateName); + } } } @@ -683,7 +722,8 @@ usage(void) if (current_app_type->app_type == PCP_WATCHDOG_INFO) { fprintf(stderr, " -n, --watchdog-id=ID ID of a other pgpool to get information for\n"); - fprintf(stderr, " If omitted then get one's self information\n"); + fprintf(stderr, " ID 0 for the local watchdog\n"); + fprintf(stderr, " If omitted then get information of all watchdog nodes\n"); } if (current_app_type->app_type == PCP_PROC_INFO) { diff --git a/src/utils/json.c b/src/utils/json.c index 56b024fda..79587e80e 100644 --- a/src/utils/json.c +++ b/src/utils/json.c @@ -59,15 +59,20 @@ const struct _json_value json_value_none; #include "pool.h" -#include "utils/palloc.h" -#include "utils/memutils.h" -#include "utils/elog.h" #include <stdio.h> #include <string.h> #include <ctype.h> #include <math.h> +#ifndef POOL_PRIVATE +#include "utils/palloc.h" +#include "utils/memutils.h" +#include "utils/elog.h" +#else +#include "utils/fe_ports.h" +#endif + typedef unsigned int json_uchar; static unsigned char hex_value (json_char c) diff --git a/src/utils/pcp/pcp_stream.c b/src/utils/pcp/pcp_stream.c index 5d95964e3..29dca9726 100644 --- a/src/utils/pcp/pcp_stream.c +++ b/src/utils/pcp/pcp_stream.c @@ -4,7 +4,7 @@ * pgpool: a language independent connection pool server for PostgreSQL * written by Tatsuo Ishii * - * Copyright (c) 2003-2014 PgPool Global Development Group + * Copyright (c) 2003-2015 PgPool Global Development Group * * Permission to use, copy, modify, and distribute this software and * its documentation for any purpose and without fee is hereby diff --git a/src/watchdog/watchdog.c b/src/watchdog/watchdog.c index cf51b1c73..572e8df60 100644 --- a/src/watchdog/watchdog.c +++ b/src/watchdog/watchdog.c @@ -148,14 +148,14 @@ char *wd_state_names[] = { "LOADING", "JOINING", "INITIALIZING", - "COORDINATOR", - "PARTICIPATE_IN_ELECTION", - "STAND_FOR_COORDINATOR", + "MASTER", + "PARTICIPATING IN ELECTION", + "STANDING FOR MASTER", "STANDBY", "LOST", - "IN_NETWORK_TROUBLE", + "IN NETWORK TROUBLE", "SHUTDOWN", - "ADD_MESSAGE_SENT"}; + "ADD MESSAGE SENT"}; typedef struct WDPacketData { @@ -266,11 +266,9 @@ typedef struct wd_cluster int command_server_sock; int network_monitor_sock; bool holding_vip; - bool network_error; bool escalated; bool clusterInitialized; bool ipc_auth_needed; - struct timeval network_error_time; List *unidentified_socks; List *notify_clients; @@ -1521,7 +1519,6 @@ static IPC_CMD_PREOCESS_RES process_IPC_nodeList_command(WDIPCCommandData* IPCCo return IPC_CMD_ERROR; } - /* If it is a node function ?*/ if (json_get_int_value_for_key(root, "NodeID", &NodeID)) { json_value_free(root); @@ -2513,10 +2510,12 @@ static bool add_nodeinfo_to_json(JsonNode* jNode, WatchdogNode* node) jw_put_int(jNode, "State",node?node->state:-1); jw_put_string(jNode, "NodeName",node?node->nodeName:"Not Set"); jw_put_string(jNode, "HostName", node?node->hostname:"Not Set"); + jw_put_string(jNode, "StateName", node?wd_state_names[node->state]:"Not Set"); jw_put_string(jNode, "DelegateIP",node?node->delegate_ip:"Not Set"); jw_put_int(jNode, "WdPort", node?node->wd_port:0); jw_put_int(jNode, "PgpoolPort", node?node->pgpool_port:0); - + jw_put_int(jNode, "Priority", node?node->wd_priority:0); + jw_end_element(jNode); return true; @@ -2526,15 +2525,23 @@ static JsonNode* get_node_list_json(int id) { int i; JsonNode* jNode = jw_create_with_object(true); - /* add the node count */ + update_connected_node_count(); + update_quorum_status(); + jw_put_int(jNode, "RemoteNodeCount", g_cluster.remoteNodeCount); + jw_put_int(jNode, "QuorumStatus", g_cluster.quorum_status); + jw_put_int(jNode, "AliveNodeCount", g_cluster.aliveNodeCount); + jw_put_int(jNode, "Escalated", g_cluster.escalated?1:0); + jw_put_string(jNode, "MasterNodeName",g_cluster.masterNode?g_cluster.masterNode->nodeName:"Not Set"); + jw_put_string(jNode, "MasterHostName",g_cluster.masterNode?g_cluster.masterNode->hostname:"Not Set"); if (id < 0) { jw_put_int(jNode, "NodeCount", g_cluster.remoteNodeCount + 1); + /* add the array */ jw_start_array(jNode, "WatchdogNodes"); /* add the local node info */ add_nodeinfo_to_json(jNode,g_cluster.localNode); - /* add remote nodes */ + /* add all remote nodes */ for (i=0; i< g_cluster.remoteNodeCount; i++) { WatchdogNode* wdNode = &(g_cluster.remoteNodes[i]); @@ -2544,6 +2551,9 @@ static JsonNode* get_node_list_json(int id) else { jw_put_int(jNode, "NodeCount", 1); + /* add the array */ + jw_start_array(jNode, "WatchdogNodes"); + if (id == 0) { /* add the local node info */ @@ -5134,7 +5144,6 @@ static bool check_IPC_client_authentication(json_value *rootObj, bool internal_c return false; } - /* If it is a node function ?*/ if (has_shared_key == false) { ereport(LOG, diff --git a/src/watchdog/wd_json_data.c b/src/watchdog/wd_json_data.c index 7d567f895..df97d70d0 100644 --- a/src/watchdog/wd_json_data.c +++ b/src/watchdog/wd_json_data.c @@ -368,13 +368,13 @@ WDNodeInfo* get_WDNodeInfo_from_wd_node_json(json_value* source) 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"))); } @@ -382,7 +382,7 @@ 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 Node Name"))); } strncpy(wdNodeInfo->nodeName, ptr, sizeof(wdNodeInfo->nodeName) -1); @@ -391,7 +391,7 @@ 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 Host Name"))); } strncpy(wdNodeInfo->hostName, ptr, sizeof(wdNodeInfo->hostName) -1); @@ -400,12 +400,12 @@ 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 delegate IP"))); } strncpy(wdNodeInfo->delegate_ip, ptr, sizeof(wdNodeInfo->delegate_ip) -1); - if (json_get_int_value_for_key(source, "PgpoolPort", &wdNodeInfo->wd_port)) + if (json_get_int_value_for_key(source, "WdPort", &wdNodeInfo->wd_port)) { ereport(ERROR, (errmsg("invalid json data"), @@ -418,13 +418,29 @@ WDNodeInfo* get_WDNodeInfo_from_wd_node_json(json_value* source) (errmsg("invalid json data"), errdetail("unable to find PgpoolPort"))); } - + if (json_get_int_value_for_key(source, "State", &wdNodeInfo->state)) { ereport(ERROR, (errmsg("invalid json data"), errdetail("unable to find state"))); } + + ptr = json_get_string_value_for_key(source, "StateName"); + if (ptr == NULL) + { + ereport(ERROR, + (errmsg("invalid json data"), + errdetail("unable to find Watchdog State Name"))); + } + strncpy(wdNodeInfo->stateName, ptr, sizeof(wdNodeInfo->stateName) -1); + + if (json_get_int_value_for_key(source, "Priority", &wdNodeInfo->wd_priority)) + { + ereport(ERROR, + (errmsg("invalid json data"), + errdetail("unable to find state"))); + } return wdNodeInfo; [parent: 73cad019d535]