Previously, both the watchdog and heartbeat receiver processes listen on all interfaces.
For security reasons, they now listen only on the addresses
specified by "hostname" and "heartbeat_hostname".
static bool
SetHBDestIfFunc(int elevel)
{
- int idx = 0;
+ int dest_if_idx = 0;
+ int local_if_idx = 0;
char **addrs;
char **if_names;
int i,
j,
+ k,
n_addr,
n_if_name;
+ g_pool_config.num_hb_local_if = 0;
g_pool_config.num_hb_dest_if = 0;
if (g_pool_config.wd_lifecheck_method != LIFECHECK_BY_HB)
/*
* g_pool_config.hb_ifs is the information for sending/receiving heartbeat
- * for all nodes specified in pgpool.conf. If it is local pgpool node
- * information, set dest_port to g_pool_config.wd_heartbeat_port and
- * ignore addr and if_name. g_pool_config.hb_dest_if is the heartbeat
+ * for all nodes specified in pgpool.conf. g_pool_config.hb_local_if is
+ * the local node information. g_pool_config.hb_dest_if is the heartbeat
* destination information.
*/
for (i = 0; i < WD_MAX_IF_NUM; i++)
{
if (g_pool_config.hb_ifs[i].dest_port > 0)
{
- /* Ignore local pgpool node */
- if (i == g_pool_config.pgpool_node_id)
- {
- g_pool_config.wd_heartbeat_port = g_pool_config.hb_ifs[i].dest_port;
- continue;
- }
-
WdHbIf *hbNodeInfo = &g_pool_config.hb_ifs[i];
addrs = get_list_from_string(hbNodeInfo->addr, ";", &n_addr);
if (!addrs || n_addr < 0)
{
- g_pool_config.hb_dest_if[idx].addr[0] = '\0';
+ if (i == g_pool_config.pgpool_node_id)
+ g_pool_config.hb_local_if[local_if_idx].addr[0] = '\0';
+ else
+ g_pool_config.hb_dest_if[dest_if_idx].addr[0] = '\0';
if (addrs)
pfree(addrs);
for (j = 0; j < n_addr; j++)
{
- strlcpy(g_pool_config.hb_dest_if[idx].addr, addrs[j], WD_MAX_HOST_NAMELEN - 1);
- g_pool_config.hb_dest_if[idx].dest_port = hbNodeInfo->dest_port;
- if (n_if_name > j)
+ /* local pgpool node */
+ if (i == g_pool_config.pgpool_node_id)
{
- strlcpy(g_pool_config.hb_dest_if[idx].if_name, if_names[j], WD_MAX_IF_NAME_LEN - 1);
- pfree(if_names[j]);
+ for (k = 0; k < g_pool_config.wd_nodes.num_wd - 1; k++)
+ {
+ strlcpy(g_pool_config.hb_local_if[local_if_idx].addr, addrs[j], WD_MAX_HOST_NAMELEN - 1);
+ g_pool_config.hb_local_if[local_if_idx].dest_port = hbNodeInfo->dest_port;
+
+ if (n_if_name > j )
+ strlcpy(g_pool_config.hb_local_if[local_if_idx].if_name, if_names[j], WD_MAX_IF_NAME_LEN - 1);
+ else
+ g_pool_config.hb_local_if[local_if_idx].if_name[0] = '\0';
+
+ g_pool_config.num_hb_local_if = local_if_idx + 1;
+ local_if_idx++;
+ }
+
+ if (n_if_name > j )
+ pfree(if_names[j]);
+
+ pfree(addrs[j]);
+
}
+ /* destination pgpool node */
else
- g_pool_config.hb_dest_if[idx].if_name[0] = '\0';
+ {
+ strlcpy(g_pool_config.hb_dest_if[dest_if_idx].addr, addrs[j], WD_MAX_HOST_NAMELEN - 1);
+ g_pool_config.hb_dest_if[dest_if_idx].dest_port = hbNodeInfo->dest_port;
+ if (n_if_name > j)
+ {
+ strlcpy(g_pool_config.hb_dest_if[dest_if_idx].if_name, if_names[j], WD_MAX_IF_NAME_LEN - 1);
+ pfree(if_names[j]);
+ }
+ else
+ g_pool_config.hb_dest_if[dest_if_idx].if_name[0] = '\0';
- g_pool_config.num_hb_dest_if = idx + 1;
- idx++;
- pfree(addrs[j]);
+ g_pool_config.num_hb_dest_if = dest_if_idx + 1;
+ dest_if_idx++;
+ pfree(addrs[j]);
+ }
}
if (addrs)
* lifecheck */
char *wd_lifecheck_user; /* PostgreSQL user name for watchdog */
char *wd_lifecheck_password; /* password for watchdog user */
- int wd_heartbeat_port; /* Port number for heartbeat lifecheck */
int wd_heartbeat_keepalive; /* Interval time of sending heartbeat
* signal (sec) */
int wd_heartbeat_deadtime; /* Deadtime interval for heartbeat
* signal (sec) */
WdHbIf hb_ifs[WD_MAX_IF_NUM]; /* heartbeat interfaces of all
* watchdog nodes */
+ WdHbIf hb_local_if[WD_MAX_IF_NUM]; /* local heartbeat interfaces */
+ int num_hb_local_if; /* number of local interface */
WdHbIf hb_dest_if[WD_MAX_IF_NUM]; /* heartbeat destination
* interfaces */
- int num_hb_dest_if; /* number of interface devices */
+ int num_hb_dest_if; /* number of destination interface */
char **wd_monitoring_interfaces_list; /* network interface name list
* to be monitored by watchdog */
bool health_check_test; /* if on, enable health check testing */
static bool verify_authhash_for_node(WatchdogNode *wdNode, char *authhash);
static void print_watchdog_node_info(WatchdogNode *wdNode);
-static List *wd_create_recv_socket(int port);
+static List *wd_create_recv_socket(char *hostname, int port);
static void wd_check_config(void);
static pid_t watchdog_main(void);
static pid_t fork_watchdog_child(void);
}
static List *
-wd_create_recv_socket(int port)
+wd_create_recv_socket(char *hostname, int port)
{
int one = 1;
int sock = -1;
hints.ai_protocol = 0;
hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE;
- if ((gai_ret = getaddrinfo(NULL, portstr, &hints, &res)) != 0)
+ if ((gai_ret = getaddrinfo(!hostname ? NULL : hostname, portstr, &hints, &res)) != 0)
{
ereport(ERROR,
(errmsg("getaddrinfo failed with error \"%s\"", gai_strerror(gai_ret))));
/* initialize all the local structures for watchdog */
wd_cluster_initialize();
/* create a server socket for incoming watchdog connections */
- g_wd_recv_socks = wd_create_recv_socket(g_cluster.localNode->wd_port);
+ g_wd_recv_socks = wd_create_recv_socket(g_cluster.localNode->hostname, g_cluster.localNode->wd_port);
/* open the command server */
g_cluster.command_server_sock = wd_create_command_server_socket();
*walk,
*res = NULL;
- portstr = psprintf("%d", pool_config->wd_heartbeat_port);
+ portstr = psprintf("%d", hb_if->dest_port);
memset(&hints, 0x00, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_protocol = 0;
hints.ai_flags = AI_NUMERICSERV | AI_PASSIVE;
- if ((gai_ret = getaddrinfo(NULL, portstr, &hints, &res)) != 0)
+ if ((gai_ret = getaddrinfo(!hb_if->addr ? NULL : hb_if->addr, portstr, &hints, &res)) != 0)
{
ereport(WARNING,
(errmsg("getaddrinfo() failed with error \"%s\"", gai_strerror(gai_ret))));
if (n == 0)
{
ereport(ERROR, (errmsg("failed to create watchdog heartbeat receive socket"),
- errdetail("getaddrinfo() result is empty: no sockets can be created because no available local address with port:%d", pool_config->wd_heartbeat_port)));
+ errdetail("getaddrinfo() result is empty: no sockets can be created because no available local address with port:%d", hb_if->dest_port)));
return NULL;
}
else
}
ereport(LOG,
(errmsg("creating watchdog heartbeat receive socket."),
- errdetail("creating socket on %s:%d", buf, pool_config->wd_heartbeat_port)));
+ errdetail("creating socket on %s:%d", buf, hb_if->dest_port)));
bind_is_done = 0;
for (bind_tries = 0; !bind_is_done && bind_tries < MAX_BIND_TRIES; bind_tries++)
{
int i;
- for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ for (i = 0; i < pool_config->num_hb_local_if; i++)
{
if (g_hb_receiver_pid && pid == g_hb_receiver_pid[i])
return "heartBeat receiver";
- else if (g_hb_sender_pid && pid == g_hb_sender_pid[i])
+ }
+ for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ {
+ if (g_hb_sender_pid && pid == g_hb_sender_pid[i])
return "heartBeat sender";
}
/* Check if it was a ping to trusted server process */
if (g_hb_receiver_pid == NULL && g_hb_sender_pid == NULL)
return -1;
- for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ for (i = 0; i < pool_config->num_hb_local_if; i++)
{
if (g_hb_receiver_pid && pid == g_hb_receiver_pid[i])
{
if (restart_child)
{
- g_hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_dest_if[i]));
+ g_hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_local_if[i]));
ereport(LOG,
(errmsg("fork a new %s process with pid: %d", proc_name, g_hb_receiver_pid[i])));
}
return g_hb_receiver_pid[i];
}
+ }
- else if (g_hb_sender_pid && pid == g_hb_sender_pid[i])
+ for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ {
+ if (g_hb_sender_pid && pid == g_hb_sender_pid[i])
{
if (restart_child)
{
&& g_hb_receiver_pid && g_hb_sender_pid)
{
int i;
+ pid_t pid_child;
- for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ for (i = 0; i < pool_config->num_hb_local_if; i++)
{
- pid_t pid_child = g_hb_receiver_pid[i];
+ pid_child = g_hb_receiver_pid[i];
if (pid_child > 0)
{
kill(pid_child, sig);
ret = true;
}
+ }
+ for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ {
pid_child = g_hb_sender_pid[i];
if (pid_child > 0)
{
int i;
- g_hb_receiver_pid = palloc0(sizeof(pid_t) * pool_config->num_hb_dest_if);
+ g_hb_receiver_pid = palloc0(sizeof(pid_t) * pool_config->num_hb_local_if);
g_hb_sender_pid = palloc0(sizeof(pid_t) * pool_config->num_hb_dest_if);
- for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ for (i = 0; i < pool_config->num_hb_local_if; i++)
{
/* heartbeat receiver process */
- g_hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_dest_if[i]));
+ g_hb_receiver_pid[i] = wd_hb_receiver(1, &(pool_config->hb_local_if[i]));
+ }
+ for (i = 0; i < pool_config->num_hb_dest_if; i++)
+ {
/* heartbeat sender process */
g_hb_sender_pid[i] = wd_hb_sender(1, &(pool_config->hb_dest_if[i]));
}