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]