pcp_watchdog_info displays pgpool-II watchdog's information.
Usage: pcp_watchdog_info [-d] timeout hostname port# username password [watchdogID]
-d, --debug : enable debug message (optional)
timeout : connection timeout value in seconds. command exits on timeout
hostname : pgpool-II hostname
port# : PCP port number
username : username for PCP authentication
password : password for PCP authentication
watchdogID : ID of a other pgpool to get information for
If omitted then get one's self information
rm -f $@ && ln -s $< .
bin_PROGRAMS = pcp_stop_pgpool pcp_node_count pcp_node_info pcp_proc_count pcp_proc_info \
- pcp_systemdb_info pcp_detach_node pcp_attach_node pcp_recovery_node pcp_promote_node pcp_pool_status
+ pcp_systemdb_info pcp_detach_node pcp_attach_node pcp_recovery_node pcp_promote_node \
+ pcp_pool_status pcp_watchdog_info
pcp_stop_pgpool_SOURCES = pcp_stop_pgpool.c pcp.h ../getopt_long.c ../getopt_long.h
pcp_stop_pgpool_LDADD = libpcp.la
pcp_stop_pgpool_LDFLAGS =
pcp_pool_status_LDADD = libpcp.la
pcp_promote_node_SOURCES = pcp_promote_node.c pcp.h ../getopt_long.c ../getopt_long.h
pcp_promote_node_LDADD = libpcp.la
+pcp_watchdog_info_SOURCES = pcp_watchdog_info.c pcp.h ../getopt_long.c ../getopt_long.h
+pcp_watchdog_info_LDADD = libpcp.la
pcp_proc_info$(EXEEXT) pcp_systemdb_info$(EXEEXT) \
pcp_detach_node$(EXEEXT) pcp_attach_node$(EXEEXT) \
pcp_recovery_node$(EXEEXT) pcp_promote_node$(EXEEXT) \
- pcp_pool_status$(EXEEXT)
+ pcp_pool_status$(EXEEXT) pcp_watchdog_info$(EXEEXT)
subdir = pcp
DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
getopt_long.$(OBJEXT)
pcp_systemdb_info_OBJECTS = $(am_pcp_systemdb_info_OBJECTS)
pcp_systemdb_info_DEPENDENCIES = libpcp.la
+am_pcp_watchdog_info_OBJECTS = pcp_watchdog_info.$(OBJEXT) \
+ getopt_long.$(OBJEXT)
+pcp_watchdog_info_OBJECTS = $(am_pcp_watchdog_info_OBJECTS)
+pcp_watchdog_info_DEPENDENCIES = libpcp.la
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
$(pcp_node_info_SOURCES) $(pcp_pool_status_SOURCES) \
$(pcp_proc_count_SOURCES) $(pcp_proc_info_SOURCES) \
$(pcp_promote_node_SOURCES) $(pcp_recovery_node_SOURCES) \
- $(pcp_stop_pgpool_SOURCES) $(pcp_systemdb_info_SOURCES)
+ $(pcp_stop_pgpool_SOURCES) $(pcp_systemdb_info_SOURCES) \
+ $(pcp_watchdog_info_SOURCES)
DIST_SOURCES = $(libpcp_la_SOURCES) $(pcp_attach_node_SOURCES) \
$(pcp_detach_node_SOURCES) $(pcp_node_count_SOURCES) \
$(pcp_node_info_SOURCES) $(pcp_pool_status_SOURCES) \
$(pcp_proc_count_SOURCES) $(pcp_proc_info_SOURCES) \
$(pcp_promote_node_SOURCES) $(pcp_recovery_node_SOURCES) \
- $(pcp_stop_pgpool_SOURCES) $(pcp_systemdb_info_SOURCES)
+ $(pcp_stop_pgpool_SOURCES) $(pcp_systemdb_info_SOURCES) \
+ $(pcp_watchdog_info_SOURCES)
HEADERS = $(include_HEADERS)
ETAGS = etags
CTAGS = ctags
pcp_pool_status_LDADD = libpcp.la
pcp_promote_node_SOURCES = pcp_promote_node.c pcp.h ../getopt_long.c ../getopt_long.h
pcp_promote_node_LDADD = libpcp.la
+pcp_watchdog_info_SOURCES = pcp_watchdog_info.c pcp.h ../getopt_long.c ../getopt_long.h
+pcp_watchdog_info_LDADD = libpcp.la
all: all-am
.SUFFIXES:
pcp_systemdb_info$(EXEEXT): $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_DEPENDENCIES)
@rm -f pcp_systemdb_info$(EXEEXT)
$(LINK) $(pcp_systemdb_info_OBJECTS) $(pcp_systemdb_info_LDADD) $(LIBS)
+pcp_watchdog_info$(EXEEXT): $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_DEPENDENCIES)
+ @rm -f pcp_watchdog_info$(EXEEXT)
+ $(LINK) $(pcp_watchdog_info_OBJECTS) $(pcp_watchdog_info_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_stop_pgpool.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_stream.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_systemdb_info.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcp_watchdog_info.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
QueryCacheTableInfo query_cache_table_info; /* query cache db session info */
BACKEND_STATUS system_db_status;
} SystemDBInfo;
-
/*
* reporting types
*/
char version[POOLCONFIG_MAXVALLEN+1];
} POOL_REPORT_VERSION;
+struct WdInfo;
+//typedef struct WdInfo WdInfo;
+
extern int pcp_connect(char *hostname, int port, char *username, char *password);
extern void pcp_disconnect(void);
extern int pcp_terminate_pgpool(char mode);
extern void pcp_disable_debug(void);
extern int pcp_promote_node(int nid);
extern int pcp_promote_node_gracefully(int nid);
+extern struct WdInfo *pcp_watchdog_info(int nid);
/* ------------------------------
* pcp_error.c
free(buf);
return -1;
}
+
+/* --------------------------------
+ * pcp_watchdog_info - get information of watchdog
+ *
+ * return structure of watchdog information on success, -1 otherwise
+ * --------------------------------
+ */
+WdInfo *
+pcp_watchdog_info(int nid)
+{
+ int wsize;
+ char wd_index[16];
+ char tos;
+ char *buf = NULL;
+ int rsize;
+
+ if (pc == NULL)
+ {
+ if (debug) fprintf(stderr, "DEBUG: connection does not exist\n");
+ errorcode = NOCONNERR;
+ return NULL;
+ }
+
+ snprintf(wd_index, sizeof(wd_index), "%d", nid);
+
+ pcp_write(pc, "W", 1);
+ wsize = htonl(strlen(wd_index)+1 + sizeof(int));
+ pcp_write(pc, &wsize, sizeof(int));
+ pcp_write(pc, wd_index, strlen(wd_index)+1);
+ if (pcp_flush(pc) < 0)
+ {
+ if (debug) fprintf(stderr, "DEBUG: could not send data to backend\n");
+ return NULL;
+ }
+ if (debug) fprintf(stderr, "DEBUG: send: tos=\"W\", len=%d\n", ntohl(wsize));
+
+ if (pcp_read(pc, &tos, 1))
+ return NULL;
+ if (pcp_read(pc, &rsize, sizeof(int)))
+ return NULL;
+ rsize = ntohl(rsize);
+ buf = (char *)malloc(rsize);
+ if (buf == NULL)
+ {
+ errorcode = NOMEMERR;
+ return NULL;
+ }
+ if (pcp_read(pc, buf, rsize - sizeof(int)))
+ {
+ free(buf);
+ return NULL;
+ }
+
+ if (debug) fprintf(stderr, "DEBUG: recv: tos=\"%c\", len=%d, data=%s\n", tos, rsize, buf);
+
+ if (tos == 'e')
+ {
+ if (debug) fprintf(stderr, "DEBUG: command failed. reason=%s\n", buf);
+ errorcode = BACKENDERR;
+ free(buf);
+ return NULL;
+ }
+ else if (tos == 'w')
+ {
+ if (strcmp(buf, "CommandComplete") == 0)
+ {
+ char *index = NULL;
+ WdInfo* watchdog_info = NULL;
+
+ watchdog_info = (WdInfo *)malloc(sizeof(WdInfo));
+ if (watchdog_info == NULL)
+ {
+ errorcode = NOMEMERR;
+ free(buf);
+ return NULL;
+ }
+
+ index = (char *) memchr(buf, '\0', rsize) + 1;
+ if (index != NULL)
+ strcpy(watchdog_info->hostname, index);
+
+ index = (char *) memchr(index, '\0', rsize) + 1;
+ if (index != NULL)
+ watchdog_info->pgpool_port = atoi(index);
+
+ index = (char *) memchr(index, '\0', rsize) + 1;
+ if (index != NULL)
+ watchdog_info->wd_port = atoi(index);
+
+ index = (char *) memchr(index, '\0', rsize) + 1;
+ if (index != NULL)
+ watchdog_info->status = atof(index);
+
+ free(buf);
+ return watchdog_info;
+ }
+ }
+
+ free(buf);
+}
#define PCP_H
#include "pool_type.h"
+#include "watchdog/watchdog.h"
#define MAX_USER_PASSWD_LEN 128
--- /dev/null
+/*
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Copyright (c) 2003-2013 PgPool Global Development Group
+ *
+ * Permission to use, copy, modify, and distribute this software and
+ * its documentation for any purpose and without fee is hereby
+ * granted, provided that the above copyright notice appear in all
+ * copies and that both that copyright notice and this permission
+ * notice appear in supporting documentation, and that the name of the
+ * author not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. The author makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * Client program to send "watchdog info" command.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#include "getopt_long.h"
+#endif
+
+#include "pcp.h"
+
+static void usage(void);
+static void myexit(ErrorCode e);
+
+int
+main(int argc, char **argv)
+{
+ long timeout;
+ char host[MAX_DB_HOST_NAMELEN];
+ int port;
+ char user[MAX_USER_PASSWD_LEN];
+ char pass[MAX_USER_PASSWD_LEN];
+ int wd_index;
+ WdInfo *watchdog_info;
+ int ch;
+ int optindex;
+ bool verbose = false;
+
+ static struct option long_options[] = {
+ {"debug", no_argument, NULL, 'd'},
+ {"help", no_argument, NULL, 'h'},
+ {"verbose", no_argument, NULL, 'v'},
+ {NULL, 0, NULL, 0}
+ };
+
+ while ((ch = getopt_long(argc, argv, "hdv", long_options, &optindex)) != -1) {
+ switch (ch) {
+ case 'd':
+ pcp_enable_debug();
+ break;
+
+ case 'v':
+ verbose = true;
+ break;
+
+ case 'h':
+ case '?':
+ default:
+ usage();
+ exit(0);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (!(argc == 5 || argc == 6))
+ {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+
+ timeout = atol(argv[0]);
+ if (timeout < 0) {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+
+ if (strlen(argv[1]) >= MAX_DB_HOST_NAMELEN)
+ {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+ strcpy(host, argv[1]);
+
+ port = atoi(argv[2]);
+ if (port <= 1024 || port > 65535)
+ {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+
+ if (strlen(argv[3]) >= MAX_USER_PASSWD_LEN)
+ {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+ strcpy(user, argv[3]);
+
+ if (strlen(argv[4]) >= MAX_USER_PASSWD_LEN)
+ {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+ strcpy(pass, argv[4]);
+
+ if (argc == 6)
+ {
+ wd_index = atoi(argv[5]);
+ if (wd_index < 0 || wd_index > MAX_WATCHDOG_NUM)
+ {
+ errorcode = INVALERR;
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+ wd_index++;
+ }
+ else
+ {
+ wd_index = 0;
+ }
+
+ pcp_set_timeout(timeout);
+
+ if (pcp_connect(host, port, user, pass))
+ {
+ pcp_errorstr(errorcode);
+ myexit(errorcode);
+ }
+
+ if ((watchdog_info = pcp_watchdog_info(wd_index)) == NULL)
+ {
+ pcp_errorstr(errorcode);
+ pcp_disconnect();
+ myexit(errorcode);
+ }
+ else
+ {
+ if (verbose)
+ {
+ printf("Hostname : %s\nPgpool port : %d\nWatchdog port: %d\nStatus : %d\n",
+ watchdog_info->hostname,
+ watchdog_info->pgpool_port,
+ watchdog_info->wd_port,
+ watchdog_info->status);
+ }
+ else
+ {
+ printf("%s %d %d %d\n",
+ watchdog_info->hostname,
+ watchdog_info->pgpool_port,
+ watchdog_info->wd_port,
+ watchdog_info->status);
+ }
+
+ free(watchdog_info);
+ }
+
+ pcp_disconnect();
+
+ return 0;
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "pcp_watchdog_info - display a pgpool-II watchdog's information\n\n");
+ fprintf(stderr, "Usage: pcp_watchdog_info [-d] timeout hostname port# username password [watchdogID]\n");
+ fprintf(stderr, " -d, --debug : enable debug message (optional)\n");
+ fprintf(stderr, " timeout : connection timeout value in seconds. command exits on timeout\n");
+ fprintf(stderr, " hostname : pgpool-II hostname\n");
+ fprintf(stderr, " port# : PCP port number\n");
+ fprintf(stderr, " username : username for PCP authentication\n");
+ fprintf(stderr, " password : password for PCP authentication\n");
+ fprintf(stderr, " watchdogID : ID of a other pgpool to get information for\n");
+ fprintf(stderr, " If omitted then get one's self information\n\n");
+ fprintf(stderr, "Usage: pcp_watchdog_info [options]\n");
+ fprintf(stderr, " Options available are:\n");
+ fprintf(stderr, " -h, --help : print this help\n");
+ fprintf(stderr, " -v, --verbose : display one line per information with a header\n");
+}
+
+static void
+myexit(ErrorCode e)
+{
+ if (e == INVALERR)
+ {
+ usage();
+ exit(e);
+ }
+
+ exit(e);
+}
#include "pool_config.h"
#include "pool_process_context.h"
#include "pool_process_reporting.h"
+#include "watchdog/wd_ext.h"
#define MAX_FILE_LINE_LEN 512
#define MAX_USER_PASSWD_LEN 128
break;
}
+ case 'W': /* watchdog info */
+ {
+ int wd_index;
+ int wsize;
+
+ WdInfo *wi = NULL;
+
+ if (!pool_config->use_watchdog)
+ {
+ char code[] = "watchdog not enabled";
+
+ pcp_write(frontend, "e", 1);
+ wsize = htonl(sizeof(code) + sizeof(int));
+ pcp_write(frontend, &wsize, sizeof(int));
+ pcp_write(frontend, code, sizeof(code));
+ if (pcp_flush(frontend) < 0)
+ {
+ pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
+ exit(1);
+ }
+
+ pool_debug("pcp_child: watcdhog not enabled");
+ break;
+ }
+
+ wd_index = atoi(buf);
+ wi = wd_get_watchdog_info(wd_index);
+
+ if (wi == NULL) {
+ char code[] = "Invalid watchdog index";
+
+ pcp_write(frontend, "e", 1);
+ wsize = htonl(sizeof(code) + sizeof(int));
+ pcp_write(frontend, &wsize, sizeof(int));
+ pcp_write(frontend, code, sizeof(code));
+ if (pcp_flush(frontend) < 0)
+ {
+ pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
+ exit(1);
+ }
+
+ pool_debug("pcp_child: invalid watchdog index");
+ }
+ else
+ {
+ char code[] = "CommandComplete";
+ char pgpool_port_str[6];
+ char wd_port_str[6];
+ char status[2];
+
+ snprintf(pgpool_port_str, sizeof(pgpool_port_str), "%d", wi->pgpool_port);
+ snprintf(wd_port_str, sizeof(wd_port_str), "%d", wi->wd_port);
+ snprintf(status, sizeof(status), "%d", wi->status);
+
+ pcp_write(frontend, "w", 1);
+ wsize = htonl(sizeof(code) +
+ strlen(wi->hostname)+1 +
+ strlen(pgpool_port_str)+1 +
+ strlen(wd_port_str)+1 +
+ strlen(status)+1 +
+ sizeof(int));
+ pcp_write(frontend, &wsize, sizeof(int));
+ pcp_write(frontend, code, sizeof(code));
+
+ pcp_write(frontend, wi->hostname, strlen(wi->hostname)+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);
+ if (pcp_flush(frontend) < 0)
+ {
+ pool_error("pcp_child: pcp_flush() failed. reason: %s", strerror(errno));
+ exit(1);
+ }
+
+ pool_debug("pcp_child: retrieved node information from shared memory");
+ }
+ break;
+ }
+
case 'D': /* detach node */
case 'd': /* detach node gracefully */
{
/*
* watchdog list
*/
-typedef struct {
+typedef struct WdInfo {
WD_STATUS status; /* status */
struct timeval tv; /* startup time value */
char hostname[WD_MAX_HOST_NAMELEN]; /* host name */
extern void wd_set_interlocking(WdInfo *info, bool value);
extern void wd_clear_interlocking_info(void);
extern bool wd_is_contactable_master(void);
+extern WdInfo * wd_get_watchdog_info(int num);
/* wd_packet.c */
extern int wd_startup(void);
return false;
}
+
+/*
+ * get watchdog information of specified index
+ */
+WdInfo *
+wd_get_watchdog_info(int wd_index)
+{
+ if (wd_index < 0 || wd_index > pool_config->other_wd->num_wd)
+ return NULL;
+
+ return &WD_List[wd_index];
+}