Example #1
0
int
wd_set_wd_info(WdInfo * info)
{
	int rtn;
	rtn = wd_set_wd_list(info->hostname, info->pgpool_port, info->wd_port, info->delegate_ip, &(info->tv), info->status);
	return rtn;
}
Example #2
0
int
wd_escalation(void)
{
	int rtn;

	pool_log("wd_escalation: escalating to master pgpool");

	/* clear shared memory cache */
	if (pool_config->memory_cache_enabled && pool_is_shmem_cache() &&
	    pool_config->clear_memqcache_on_escalation)
	{
		pool_log("wd_escalation: clear all the query cache on shared memory");
		pool_clear_memory_cache();
	}

	/* execute escalation command */
	if (strlen(pool_config->wd_escalation_command))
	{
		system(pool_config->wd_escalation_command);
	}

	/* interface up as delegate IP */
	if (strlen(pool_config->delegate_IP) != 0)
		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, pool_config->delegate_IP,
	               NULL, WD_MASTER);

	/* send declare packet */
	rtn = wd_declare();
	if (rtn == WD_OK)
	{
		pool_log("wd_escalation: escalated to master pgpool successfully");
	}

	return rtn;
}
Example #3
0
static int
wd_send_response(int sock, WdPacket * recv_pack)
{
	int rtn = WD_NG;
	WdInfo * p, *q;
	WdNodeInfo * node;
	WdLockInfo * lock;
	WdPacket send_packet;
	struct timeval tv;
	char pack_str[WD_MAX_PACKET_STRING];
	int pack_str_len;
	char hash[(MD5_PASSWD_LEN+1)*2];
	bool is_node_packet = false;

	if (recv_pack == NULL)
	{
		return rtn;
	}
	memset(&send_packet, 0, sizeof(WdPacket));
	p = &(recv_pack->wd_body.wd_info);	

	/* auhtentication */
	if (strlen(pool_config->wd_authkey))
	{
		/* calculate hash from packet */
		pack_str_len = wd_packet_to_string(*recv_pack, pack_str, sizeof(pack_str));
		wd_calc_hash(pack_str, pack_str_len, hash);

		if (strcmp(recv_pack->hash, hash))
		{
			pool_log("wd_send_response: watchdog authentication failed");
			rtn = wd_authentication_failed(sock);
			return rtn;
		}
	}

	/* set response packet no */
	switch (recv_pack->packet_no)
	{
		/* 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->delegate_ip, &(p->tv), p->status) > 0)
			{
				send_packet.packet_no = WD_ADD_ACCEPT;
			}
			else
			{
				send_packet.packet_no = WD_ADD_REJECT;
			}
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			break;

		/* 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->delegate_ip, &(p->tv), p->status);
			/* check exist master */
			if ((q = wd_is_alive_master()) != NULL)
			{
				/* vote against the candidate */
				send_packet.packet_no = WD_MASTER_EXIST;
				memcpy(&(send_packet.wd_body.wd_info), q, sizeof(WdInfo));
			}
			else
			{
				if (WD_MYSELF->tv.tv_sec <= p->tv.tv_sec )
				{
					memcpy(&tv,&(p->tv),sizeof(struct timeval));
					tv.tv_sec += 1;
					wd_set_myself(&tv, WD_NORMAL);
				}
				/* vote for the candidate */
				send_packet.packet_no = WD_VOTE_YOU;
				memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			}
			break;

		/* 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->delegate_ip, &(p->tv), p->status);
			if (WD_MYSELF->status == WD_MASTER)
			{
				/* resign master server */
				pool_log("wd_declare_new_master: ifconfig down to resign master server");
				wd_IP_down();
				wd_set_myself(NULL, WD_NORMAL);
			}
			send_packet.packet_no = WD_READY;
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			break;

		/* annouce to assume lock holder */
		case WD_STAND_FOR_LOCK_HOLDER:
			p = &(recv_pack->wd_body.wd_info);	
			wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
			/* only master handles lock holder privilege */
			if (WD_MYSELF->status == WD_MASTER)
			{
				/* if theare are no lock holder yet */
				if (wd_get_lock_holder() != NULL)
				{
					send_packet.packet_no = WD_LOCK_HOLDER_EXIST;
				}
			}
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			break;

		case WD_DECLARE_LOCK_HOLDER:
			p = &(recv_pack->wd_body.wd_info);	
			wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
			wd_set_lock_holder(p, true);
			send_packet.packet_no = WD_READY;
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			break;

		/* annouce to resigne lock holder */
		case WD_RESIGN_LOCK_HOLDER:
			p = &(recv_pack->wd_body.wd_info);	
			wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
			wd_set_lock_holder(p, false);
			send_packet.packet_no = WD_READY;
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			break;

		case WD_START_INTERLOCK:
			p = &(recv_pack->wd_body.wd_info);	
			wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
			wd_set_interlocking(p, true);
			break;

		case WD_END_INTERLOCK:
			p = &(recv_pack->wd_body.wd_info);	
			wd_set_wd_list(p->hostname,p->pgpool_port, p->wd_port, p->delegate_ip, &(p->tv), p->status);
			wd_set_interlocking(p, false);
			break;

		/* 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->delegate_ip, &(p->tv), WD_DOWN);
			send_packet.packet_no = WD_READY;
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			if (wd_am_I_oldest() == WD_OK && WD_MYSELF->status != WD_MASTER)
			{
				wd_escalation();
			}
			break;

		/* announce start online recovery */
		case WD_START_RECOVERY:
			if (*InRecovery != RECOVERY_INIT)
			{
				send_packet.packet_no = WD_NODE_FAILED;
			}
			else
			{
				send_packet.packet_no = WD_NODE_READY;
				*InRecovery = RECOVERY_ONLINE;
				if (wait_connection_closed() != 0)
				{
					send_packet.packet_no = WD_NODE_FAILED;
				}
			}
			break;
		case WD_END_RECOVERY:
			send_packet.packet_no = WD_NODE_READY;
			*InRecovery = RECOVERY_INIT;
			kill(wd_ppid, SIGUSR2);
			break;
		case WD_FAILBACK_REQUEST:
			node = &(recv_pack->wd_body.wd_node_info);	
			wd_set_node_mask(WD_FAILBACK_REQUEST,node->node_id_set,node->node_num);
			is_node_packet = true;
			send_packet.packet_no = WD_NODE_READY;
			break;
		case WD_DEGENERATE_BACKEND:
			node = &(recv_pack->wd_body.wd_node_info);	
			wd_set_node_mask(WD_DEGENERATE_BACKEND,node->node_id_set, node->node_num);
			is_node_packet = true;
			send_packet.packet_no = WD_NODE_READY;
			break;
		case WD_PROMOTE_BACKEND:
			node = &(recv_pack->wd_body.wd_node_info);	
			wd_set_node_mask(WD_PROMOTE_BACKEND,node->node_id_set, node->node_num);
			is_node_packet = true;
			send_packet.packet_no = WD_NODE_READY;
			break;

		case WD_UNLOCK_REQUEST:
			lock = &(recv_pack->wd_body.wd_lock_info);	
			wd_set_lock(lock->lock_id, false);
			send_packet.packet_no = WD_LOCK_READY;
			break;

		default:
			send_packet.packet_no = WD_INVALID;
			memcpy(&(send_packet.wd_body.wd_info), WD_MYSELF, sizeof(WdInfo));
			break;
	}

	/* send response packet */
	rtn = wd_send_packet(sock, &send_packet);

	/* send node request signal.
	 * wd_node_request_singnal() uses a semaphore lock internally, so should be
	 * called after sending a response pakcet to prevent dead lock.
	 */
	if (is_node_packet)
		wd_node_request_signal(recv_pack->packet_no, node);

	return rtn;
}
Example #4
0
int
wd_init(void)
{
	struct timeval tv;
	WdInfo * p;

	/* set startup time */
	gettimeofday(&tv, NULL);

	/* allocate watchdog list */
	if (WD_List == NULL)
	{
		WD_List = pool_shared_memory_create(sizeof(WdInfo) * MAX_WATCHDOG_NUM);
		if (WD_List == NULL)
		{
			pool_error("wd_init: failed to allocate watchdog list");
			return WD_NG;
		}
		memset(WD_List, 0, sizeof(WdInfo) * MAX_WATCHDOG_NUM);
	}

	/* allocate node list */
	if (WD_Node_List == NULL)
	{
		WD_Node_List = pool_shared_memory_create(sizeof(unsigned char) * MAX_NUM_BACKENDS);
		if (WD_Node_List == NULL)
		{
			pool_error("wd_init: failed to allocate node list");
			return WD_NG;
		}
		memset(WD_Node_List, 0, sizeof(unsigned char) * MAX_NUM_BACKENDS);
	}

	/* initialize interlock */
	if (wd_init_interlock() != WD_OK)
	{
		pool_error("wd_init: wd_init_interlock failed");
		return WD_NG;
	}

	/* set myself to watchdog list */
	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);

	/* reset time value */
	p = WD_List;
	while (p->status != WD_END)
	{
		WD_TIME_INIT(p->hb_send_time);
		WD_TIME_INIT(p->hb_last_recv_time);

		p++;
	}

	/* check upper connection */
	if (strlen(pool_config->trusted_servers) &&
		wd_is_upper_ok(pool_config->trusted_servers) != WD_OK)
	{
		pool_error("wd_init: failed to connect trusted server");
		return WD_NG;
	}

	/* send startup packet */
	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 (strlen(pool_config->delegate_IP) != 0 &&
		    !wd_is_unused_ip(pool_config->delegate_IP))
		{
			pool_error("wd_init: delegate_IP %s already exists", pool_config->delegate_IP);
			return WD_NG;
		}

		/* escalate to delegate_IP holder */
		wd_escalation();
	}

	pool_log("wd_init: start watchdog");
	return WD_OK;	
}
Example #5
0
void
wd_init(void)
{
	struct timeval tv;
	WdInfo * p;

	/* set startup time */
	gettimeofday(&tv, NULL);

	/* allocate watchdog list */
	if (WD_List == NULL)
	{
		WD_List = pool_shared_memory_create(sizeof(WdInfo) * MAX_WATCHDOG_NUM);
		memset(WD_List, 0, sizeof(WdInfo) * MAX_WATCHDOG_NUM);

		ereport(DEBUG1,
				(errmsg("WD_List: sizeof(WdInfo) (%zu) * MAX_WATCHDOG_NUM (%d) = %zu bytes requested for shared memory",
						sizeof(WdInfo),
						MAX_WATCHDOG_NUM,
						sizeof(WdInfo) * MAX_WATCHDOG_NUM)));
	}

	/* allocate node list */
	if (WD_Node_List == NULL)
	{
		WD_Node_List = pool_shared_memory_create(sizeof(unsigned char) * MAX_NUM_BACKENDS);
		memset(WD_Node_List, 0, sizeof(unsigned char) * MAX_NUM_BACKENDS);

		ereport(DEBUG1,
				(errmsg("WD_Node_List: sizeof(unsigned char) (%zu) * MAX_NUM_BACKENDS (%d) = %zu bytes requested for shared memory",
						sizeof(unsigned char),
						MAX_WATCHDOG_NUM,
						sizeof(unsigned char) * MAX_NUM_BACKENDS)));
	}

	/* initialize interlock */
	wd_init_interlock();

	/* set myself to watchdog list */
	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);

	/* reset time value */
	p = WD_List;
	while (p->status != WD_END)
	{
		WD_TIME_INIT(p->hb_send_time);
		WD_TIME_INIT(p->hb_last_recv_time);

		p++;
	}

	/* check upper connection */
	if (strlen(pool_config->trusted_servers) &&
		wd_is_upper_ok(pool_config->trusted_servers) != WD_OK)
	{
		ereport(ERROR,
			(errmsg("failed to initialize watchdog, failed to connect to trusted server")));
	}
	/* send startup packet */
	if (wd_startup() == WD_NG)
	{
		ereport(ERROR,
				(errmsg("failed to initialize watchdog, startup failed")));
	}
	/* check existence of master pgpool */
	if (wd_is_exist_master() == NULL)
	{
		if (strlen(pool_config->delegate_IP) != 0 &&
		    !wd_is_unused_ip(pool_config->delegate_IP))
		{
			ereport(ERROR,
				(errmsg("failed to initialize watchdog, delegate_IP \"%s\" already exists", pool_config->delegate_IP)));
		}
		/* escalate to delegate_IP holder */
		wd_escalation();
	}
	ereport(LOG,
		(errmsg("watchdog started")));
}