pgpool2.git / summary / log / commit / refs
commit 42c6bba448c242acd7433c46bfa9259ee9e38f94
Author: Yugo Nagata <nagata@sraoss.co.jp>
Date: Mon Jul 30 04:52:29 2012 +0000
Add a check of if the delegate IP is unused when watchdog starting.
watchdog/watchdog.h | 3 ++-
watchdog/wd_child.c | 8 ++++----
watchdog/wd_ext.h | 3 ++-
watchdog/wd_if.c | 8 ++++----
watchdog/wd_init.c | 9 ++++++++-
watchdog/wd_list.c | 21 +++++++++++++++------
watchdog/wd_packet.c | 4 +++-
watchdog/wd_ping.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 83 insertions(+), 18 deletions(-)
diff --git a/watchdog/watchdog.h b/watchdog/watchdog.h
index 31a0557e9..cff31f5de 100644
--- a/watchdog/watchdog.h
+++ b/watchdog/watchdog.h
@@ -82,7 +82,8 @@ typedef struct {
int pgpool_port; /* pgpool port */
int wd_port; /* watchdog port */
int life; /* life point */
- int delegate_ip; /* delegate IP flag */
+ char delegate_ip[WD_MAX_HOST_NAMELEN]; /* delegate IP */
+ int delegate_ip_flag; /* delegate IP flag */
}WdInfo;
typedef struct {
diff --git a/watchdog/wd_child.c b/watchdog/wd_child.c
index 4afc8253f..96c43f9cd 100644
--- a/watchdog/wd_child.c
+++ b/watchdog/wd_child.c
@@ -142,7 +142,7 @@ send_response(int sock, WdPacket * recv_pack)
/* add request into the watchdog list */
case WD_ADD_REQ:
p = &(recv_pack->wd_body.wd_info);
- if (wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, &(p->tv), p->status) > 0)
+ if (wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status) > 0)
{
send_packet.packet_no = WD_ADD_ACCEPT;
}
@@ -156,7 +156,7 @@ send_response(int sock, WdPacket * recv_pack)
/* announce candidacy to be the new master */
case WD_STAND_FOR_MASTER:
p = &(recv_pack->wd_body.wd_info);
- wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, &(p->tv), p->status);
+ wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
/* check exist master */
if ((q = wd_is_alive_master()) != NULL)
{
@@ -181,7 +181,7 @@ send_response(int sock, WdPacket * recv_pack)
/* announce assumption to be the new master */
case WD_DECLARE_NEW_MASTER:
p = &(recv_pack->wd_body.wd_info);
- wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, &(p->tv), p->status);
+ wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
if (WD_List->status == WD_MASTER)
{
/* resign master server */
@@ -196,7 +196,7 @@ send_response(int sock, WdPacket * recv_pack)
/* announce that server is down */
case WD_SERVER_DOWN:
p = &(recv_pack->wd_body.wd_info);
- wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, &(p->tv), WD_DOWN);
+ wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), WD_DOWN);
send_packet.packet_no = WD_READY;
memcpy(&(send_packet.wd_body.wd_info), WD_List, sizeof(WdInfo));
if (wd_am_I_oldest() == WD_OK)
diff --git a/watchdog/wd_ext.h b/watchdog/wd_ext.h
index 593fae503..dacdcb265 100644
--- a/watchdog/wd_ext.h
+++ b/watchdog/wd_ext.h
@@ -37,7 +37,7 @@ extern pid_t wd_child(int fork_wait_time);
extern int wd_init(void);
/* wd_list.c */
-extern int wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, struct timeval * tv, int status);
+extern int wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, char * delegate_ip, struct timeval * tv, int status);
extern int wd_add_wd_list(WdDesc * other_wd);
extern int wd_set_wd_info(WdInfo * info);
extern WdInfo * wd_is_exist_master(void);
@@ -64,6 +64,7 @@ extern int wd_promote_backend(int node_id);
extern int wd_set_node_mask (WD_PACKET_NO packet_no, int *node_id_set, int count);
/* wd_ping.c */
extern int wd_is_upper_ok(char * server_list);
+extern int wd_is_unnsed_ip(char * ip);
/* wd_if.c */
extern int wd_IP_up(void);
diff --git a/watchdog/wd_if.c b/watchdog/wd_if.c
index 6cbf1bef3..19a9d3700 100644
--- a/watchdog/wd_if.c
+++ b/watchdog/wd_if.c
@@ -44,9 +44,9 @@ wd_IP_up(void)
{
int rtn = WD_OK;
char path[128];
- if (WD_List->delegate_ip == 0)
+ if (WD_List->delegate_ip_flag == 0)
{
- WD_List->delegate_ip = 1;
+ WD_List->delegate_ip_flag = 1;
sprintf(path,"%s/ifconfig",pool_config->ifconfig_path);
rtn = exec_ifconfig(path,pool_config->if_up_cmd);
sprintf(path,"%s/arping",pool_config->arping_path);
@@ -59,9 +59,9 @@ wd_IP_down(void)
{
int rtn = WD_OK;
char path[128];
- if (WD_List->delegate_ip == 1)
+ if (WD_List->delegate_ip_flag == 1)
{
- WD_List->delegate_ip = 0;
+ WD_List->delegate_ip_flag = 0;
sprintf(path,"%s/ifconfig",pool_config->ifconfig_path);
rtn = exec_ifconfig(path,pool_config->if_down_cmd);
}
diff --git a/watchdog/wd_init.c b/watchdog/wd_init.c
index 4f3cb8415..5bfc2aed9 100644
--- a/watchdog/wd_init.c
+++ b/watchdog/wd_init.c
@@ -65,7 +65,7 @@ wd_init(void)
memset(WD_Node_List, 0, sizeof(unsigned char) * MAX_NUM_BACKENDS);
}
/* set myself to watchdog list */
- wd_set_wd_list(pool_config->wd_hostname, pool_config->port, pool_config->wd_port, &tv, WD_NORMAL);
+ wd_set_wd_list(pool_config->wd_hostname, pool_config->port, pool_config->wd_port, pool_config->delegate_IP, &tv, WD_NORMAL);
/* set other pgpools to watchdog list */
wd_add_wd_list(pool_config->other_wd);
@@ -82,11 +82,18 @@ wd_init(void)
if (wd_startup() == WD_NG)
{
pool_error("wd_init: failed to start watchdog");
+ return WD_NG;
}
/* check existence of master pgpool */
if (wd_is_exist_master() == NULL )
{
+ if (!wd_is_unused_ip(pool_config->delegate_IP))
+ {
+ pool_error("wd_init: delegate_IP already exists");
+ return WD_NG;
+ }
+
/* escalate to delegate_IP holder */
wd_escalation();
}
diff --git a/watchdog/wd_list.c b/watchdog/wd_list.c
index 877e85b66..bdf6ffad3 100644
--- a/watchdog/wd_list.c
+++ b/watchdog/wd_list.c
@@ -31,7 +31,7 @@
#include "watchdog.h"
#include "wd_ext.h"
-int wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, struct timeval * tv, int status);
+int wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, char * delegate_ip, struct timeval * tv, int status);
int wd_add_wd_list(WdDesc * other_wd);
int wd_set_wd_info(WdInfo * info);
WdInfo * wd_is_exist_master(void);
@@ -40,16 +40,23 @@ int wd_set_myself(struct timeval * tv, int status);
WdInfo * wd_is_alive_master(void);
int
-wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, struct timeval * tv, int status)
+wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, char * delegate_ip, struct timeval * tv, int status)
{
int i = 0;
WdInfo * p = NULL;
if ((WD_List == NULL) || (hostname == NULL))
{
- pool_error("memory allocate error");
+ pool_error("wd_set_wd_list: memory allocate error");
return -1;
}
+
+ if (strcmp(pool_config->delegate_IP, delegate_ip))
+ {
+ pool_error("wd_set_wd_list: delegate IP mismatch error");
+ return -1;
+ }
+
for ( i = 0 ; i < MAX_WATCHDOG_NUM ; i ++)
{
p = (WD_List+i);
@@ -72,6 +79,7 @@ wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, struct timeval * t
strncpy(p->hostname, hostname, sizeof(p->hostname));
p->pgpool_port = pgpool_port;
p->wd_port = wd_port;
+ strncpy(p->delegate_ip, delegate_ip, sizeof(p->delegate_ip));
if (tv != NULL)
{
memcpy(&(p->tv),tv,sizeof(struct timeval));
@@ -80,7 +88,7 @@ wd_set_wd_list(char * hostname, int pgpool_port, int wd_port, struct timeval * t
return i;
}
}
- pool_error("Can not add new watchdog information cause the WD_List is full.");
+ pool_error("wd_set_wd_list: Can not add new watchdog information cause the WD_List is full.");
return -1;
}
@@ -92,11 +100,12 @@ wd_add_wd_list(WdDesc * other_wd)
if (other_wd == NULL)
{
- pool_error("memory allocate error");
+ pool_error("wd_add_wd_list: memory allocate error");
return -1;
}
for ( i = 0 ; i < other_wd->num_wd ; i ++)
{
+ strcpy(other_wd->wd_info[i].delegate_ip, pool_config->delegate_IP);
p = &(other_wd->wd_info[i]);
wd_set_wd_info(p);
}
@@ -107,7 +116,7 @@ int
wd_set_wd_info(WdInfo * info)
{
int rtn;
- rtn = wd_set_wd_list(info->hostname, info->pgpool_port, info->wd_port, &(info->tv), info->status);
+ rtn = wd_set_wd_list(info->hostname, info->pgpool_port, info->wd_port, info->delegate_ip, &(info->tv), info->status);
return rtn;
}
diff --git a/watchdog/wd_packet.c b/watchdog/wd_packet.c
index e4b29106f..560c11f0a 100644
--- a/watchdog/wd_packet.c
+++ b/watchdog/wd_packet.c
@@ -681,6 +681,7 @@ hton_wd_packet(WdPacket * to, WdPacket * from)
to_info->pgpool_port = htonl(from_info->pgpool_port);
to_info->wd_port = htonl(from_info->wd_port);
memcpy(to_info->hostname,from_info->hostname,sizeof(to_info->hostname));
+ memcpy(to_info->delegate_ip,from_info->delegate_ip,sizeof(to_info->delegate_ip));
return WD_OK;
}
@@ -702,6 +703,7 @@ ntoh_wd_packet(WdPacket * to, WdPacket * from)
to_info->pgpool_port = ntohl(from_info->pgpool_port);
to_info->wd_port = ntohl(from_info->wd_port);
memcpy(to_info->hostname,from_info->hostname,sizeof(to_info->hostname));
+ memcpy(to_info->delegate_ip,from_info->delegate_ip,sizeof(to_info->delegate_ip));
return WD_OK;
}
@@ -758,7 +760,7 @@ wd_escalation(void)
/* interface up as delegate IP */
wd_IP_up();
/* set master status to the wd list */
- wd_set_wd_list(pool_config->wd_hostname, pool_config->port, pool_config->wd_port, NULL, WD_MASTER);
+ wd_set_wd_list(pool_config->wd_hostname, pool_config->port, pool_config->wd_port, pool_config->delegate_IP, NULL, WD_MASTER);
/* send declare packet */
rtn = wd_declare();
diff --git a/watchdog/wd_ping.c b/watchdog/wd_ping.c
index 922f12244..40e28f5ca 100644
--- a/watchdog/wd_ping.c
+++ b/watchdog/wd_ping.c
@@ -36,6 +36,7 @@
#include "watchdog.h"
int wd_is_upper_ok(char * server_list);
+int wd_is_unused_ip(char * ip);
static void * exec_ping(void * arg);
static double get_result (char * ping_data);
@@ -117,6 +118,50 @@ wd_is_upper_ok(char * server_list)
return rtn;
}
+/**
+ * check if IP addres is unused.
+ */
+int
+wd_is_unused_ip(char * ip)
+{
+ pthread_attr_t attr;
+ int rc = 0;
+ pthread_t thread;
+ WdInfo thread_arg;
+
+ int rtn = WD_NG;
+ int result;
+
+ if (ip == NULL)
+ {
+ return WD_NG;
+ }
+
+ /* thread init */
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+
+ /* set hostname as a thread_arg */
+ strncpy(thread_arg.hostname,ip,sizeof(thread_arg.hostname));
+
+ rc = pthread_create(&thread, &attr, exec_ping, (void*)&thread_arg);
+ pthread_attr_destroy(&attr);
+
+ rc = pthread_join(thread, (void **)&result);
+ if ((rc != 0) && (errno == EINTR))
+ {
+ return WD_NG;
+ }
+ if (result == WD_NG)
+ {
+ rtn = WD_OK;
+ }
+ pthread_detach(thread);
+
+ return rtn;
+}
+
+
static void *
exec_ping(void * arg)
{
[parent: 3a913b909910]