[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