[pgpool-hackers: 4202] Proposal: Add trusted_server_command parameter

Takuma Hoshiai hoshiai.takuma at nttcom.co.jp
Mon Oct 24 18:46:02 JST 2022


Hi all,

I create a patch about trusted_servers for v4.4.
Add new parameter 'trusted_server_command'.

Currently, only 'ping' command is used by trusted_servers for checking 
up stream
connection, and number of sending packets is hard coded. In some cases, 
user maybe
want to use other command.

The trusted_server_command allow users to any specify command. Default is
'ping -q -c %h' which means same as before. Pgpool-II replaces the special
characters(%h) with the host name in trusted_servers.



Best Regards,

-- 
Takuma Hoshiai <hoshiai.takuma at nttcom.co.jp>
-------------- next part --------------
 src/config/pool_config_variables.c   | 10 +++++
 src/include/pool_config.h            |  1 +
 src/include/watchdog/wd_utils.h      |  1 +
 src/sample/pgpool.conf.sample-stream |  6 +++
 src/utils/pool_process_reporting.c   |  5 +++
 src/watchdog/wd_lifecheck.c          |  9 ++--
 src/watchdog/wd_ping.c               | 80 ++++++++++++++++++++++++++++++++++++
 7 files changed, 106 insertions(+), 6 deletions(-)

diff --git a/src/config/pool_config_variables.c b/src/config/pool_config_variables.c
index fe1bfd7..c804ee1 100644
--- a/src/config/pool_config_variables.c
+++ b/src/config/pool_config_variables.c
@@ -1042,6 +1042,16 @@ static struct config_string ConfigureNamesString[] =
 	},
 
 	{
+		{"trusted_server_command", CFGCXT_RELOAD, WATCHDOG_CONFIG,
+			"Command to excute when communicate trusted server.",
+			CONFIG_VAR_TYPE_STRING, false, 0
+		},
+		&g_pool_config.trusted_server_command,
+		"ping -q -c3 %h",
+		NULL, NULL, NULL, NULL
+	},
+
+	{
 		{"delegate_IP", CFGCXT_INIT, WATCHDOG_CONFIG,
 			"Old config parameter for delegate_ip.",
 			CONFIG_VAR_TYPE_STRING, false, VAR_HIDDEN_IN_SHOW_ALL
diff --git a/src/include/pool_config.h b/src/include/pool_config.h
index b6967cf..142c6fa 100644
--- a/src/include/pool_config.h
+++ b/src/include/pool_config.h
@@ -579,6 +579,7 @@ typedef struct
 	int			pgpool_node_id;	/* pgpool (watchdog) node id */
 	WdNodesConfig wd_nodes;		/* watchdog lists */
 	char	   *trusted_servers;	/* icmp reachable server list (A,B,C) */
+	char	   *trusted_server_command;	/* Executes this command when upper servers are observed */
 	char	   *delegate_ip;	/* delegate IP address */
 	int			wd_interval;	/* lifecheck interval (sec) */
 	char	   *wd_authkey;		/* Authentication key for watchdog
diff --git a/src/include/watchdog/wd_utils.h b/src/include/watchdog/wd_utils.h
index cdf829c..604ab2d 100644
--- a/src/include/watchdog/wd_utils.h
+++ b/src/include/watchdog/wd_utils.h
@@ -52,6 +52,7 @@ 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 pid_t wd_trusted_server_command(char *hostname);
 
 /* wd_if.c */
 extern List *get_all_local_ips(void);
diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream
index 87678c7..fd34eb8 100644
--- a/src/sample/pgpool.conf.sample-stream
+++ b/src/sample/pgpool.conf.sample-stream
@@ -654,6 +654,12 @@ backend_clustering_mode = 'streaming_replication'
                                     # to confirm network connection
                                     # (hostA,hostB,hostC,...)
                                     # (change requires restart)
+
+#trusted_server_command = 'ping -q -c3 %h'
+                                    # Command to excute when communicate trusted server.
+                                    # Special values:
+                                    #   %h = host name specified by trusted_servers
+
 #ping_path = '/bin'
                                     # ping command path
                                     # (change requires restart)
diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c
index 268c174..acb32c7 100644
--- a/src/utils/pool_process_reporting.c
+++ b/src/utils/pool_process_reporting.c
@@ -820,6 +820,11 @@ get_config(int *nrows)
 	StrNCpy(status[i].desc, "upper server list to observe connection", POOLCONFIG_MAXDESCLEN);
 	i++;
 
+	StrNCpy(status[i].name, "trusted_server_command", POOLCONFIG_MAXNAMELEN);
+	snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->trusted_server_command);
+	StrNCpy(status[i].desc, "command executed when upper servers are observed", POOLCONFIG_MAXDESCLEN);
+	i++;
+
 	StrNCpy(status[i].name, "delegate_ip", POOLCONFIG_MAXNAMELEN);
 	snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->delegate_ip);
 	StrNCpy(status[i].desc, "delegate IP address of leader pgpool", POOLCONFIG_MAXDESCLEN);
diff --git a/src/watchdog/wd_lifecheck.c b/src/watchdog/wd_lifecheck.c
index e62ca01..68ae643 100644
--- a/src/watchdog/wd_lifecheck.c
+++ b/src/watchdog/wd_lifecheck.c
@@ -72,7 +72,6 @@ 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;
 
 
@@ -168,9 +167,8 @@ reaper(void)
 
 		if (server)
 		{
-			server->reachable = wd_get_ping_result(server->hostname, status, server->outputfd);
+			server->reachable = (status == 0);
 			server->pid = 0;
-			close(server->outputfd);
 		}
 		else
 			wd_reaper_lifecheck(pid, status);
@@ -1118,7 +1116,7 @@ wd_ping_all_server(void)
 		WdUpstreamConnectionData *server = (WdUpstreamConnectionData *) lfirst(lc);
 
 		if (server->pid <= 0)
-			server->pid = wd_issue_ping_command(server->hostname, &server->outputfd);
+			server->pid = wd_trusted_server_command(server->hostname);
 
 		if (server->pid > 0)
 			ping_process++;
@@ -1135,9 +1133,8 @@ wd_ping_all_server(void)
 			if (server)
 			{
 				ping_process--;
-				server->reachable = wd_get_ping_result(server->hostname, status, server->outputfd);
+				server->reachable = (status == 0);
 				server->pid = 0;
-				close(server->outputfd);
 				if (server->reachable)
 				{
 					/* one reachable server is all we need */
diff --git a/src/watchdog/wd_ping.c b/src/watchdog/wd_ping.c
index 6e758c4..d9bb322 100644
--- a/src/watchdog/wd_ping.c
+++ b/src/watchdog/wd_ping.c
@@ -155,6 +155,86 @@ wd_issue_ping_command(char *hostname, int *outfd)
 }
 
 /*
+ * execute specified command for trusted servers and return the
+ * pid of the process.
+ */
+pid_t
+wd_trusted_server_command(char *hostname)
+{
+	int			status;
+	int			pid;
+	StringInfoData		exec_cmd_data;
+	StringInfo				exec_cmd = &exec_cmd_data;
+	char *command_line = pstrdup(pool_config->trusted_server_command);
+
+	initStringInfo(exec_cmd);
+
+	while (*command_line)
+	{
+		if (*command_line == '%')
+		{
+			if (*(command_line + 1))
+			{
+				char		val = *(command_line + 1);
+
+				switch (val)
+				{
+					case 'h':	/* trusted server host name */
+						appendStringInfoString(exec_cmd, hostname);
+						break;
+
+					case '%':	/* escape */
+						appendStringInfoString(exec_cmd, "%");
+						break;
+
+					default:	/* ignore */
+						break;
+				}
+				command_line++;
+			}
+		}
+		else
+			appendStringInfoChar(exec_cmd, *command_line);
+
+		command_line++;
+	}
+
+	pid = fork();
+	if (pid == -1)
+	{
+		ereport(WARNING,
+				(errmsg("watchdog failed to ping host\"%s\"", hostname),
+				 errdetail("fork() failed. reason: %m")));
+		return -1;
+	}
+	if (pid == 0)
+	{
+		/* CHILD */
+		on_exit_reset();
+		SetProcessGlobalVariables(PT_WATCHDOG_UTILITY);
+		close(STDOUT_FILENO);
+
+		if (strlen(exec_cmd->data) != 0)
+		{
+			elog(DEBUG1, "trusted_server_command: %s", exec_cmd->data);
+			status = system(exec_cmd->data);
+		}
+
+		pfree(exec_cmd->data);
+
+		if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0)
+		{
+			ereport(FATAL,
+					(errmsg("watchdog failed to ping host\"%s\"", hostname),
+					 errdetail("system(%s) failed. reason: %m", exec_cmd->data)));
+		}
+		exit(0);
+	}
+
+	return pid;
+}
+
+/*
  * The function is helper function and can be used with the
  * wd_issue_ping_command() function to identify if the ping command
  * was successful */


More information about the pgpool-hackers mailing list