Beispiel #1
0
/*
 * Check if pgpool is alive using heartbeat signal.
 */
int
wd_check_heartbeat(WdInfo * pgpool)
{
	int interval;
	struct timeval tv;

	if (!WD_TIME_ISSET(pgpool->hb_last_recv_time) ||
	    !WD_TIME_ISSET(pgpool->hb_send_time))
	{
		ereport(DEBUG1,
			(errmsg("watchdog checking if pgpool is alive using heartbeat"),
				errdetail("pgpool (%s:%d) was restarted and has not send the heartbeat signal yet",
					   pgpool->hostname, pgpool->pgpool_port)));
		return WD_OK;
	}

	gettimeofday(&tv, NULL);

	interval = WD_TIME_DIFF_SEC(tv, pgpool->hb_last_recv_time);
	ereport(DEBUG1,
		(errmsg("watchdog checking if pgpool is alive using heartbeat"),
			errdetail("the last heartbeat from \"%s:%d\" received %d seconds ago",
				   pgpool->hostname, pgpool->pgpool_port, interval)));

	if (interval > pool_config->wd_heartbeat_deadtime)
		return WD_NG;
	else
		return WD_OK;
}
Beispiel #2
0
/*
 * Check if pgpool is alive using heartbeat signal.
 */
int
wd_check_heartbeat(WdInfo * pgpool)
{
	int interval;
	struct timeval tv;

	if (!WD_TIME_ISSET(pgpool->hb_last_recv_time) ||
	    !WD_TIME_ISSET(pgpool->hb_send_time))
	{
		pool_debug("wd_check_heartbeat: pgpool (%s:%d) was restarted and has not send the heartbeat signal yet",
		           pgpool->hostname, pgpool->pgpool_port);
		return WD_OK;
	}

	gettimeofday(&tv, NULL);

	interval = WD_TIME_DIFF_SEC(tv, pgpool->hb_last_recv_time);
	pool_debug("wd_check_heartbeat: the latest heartbeat from %s:%d received %d seconds ago",
	           pgpool->hostname, pgpool->pgpool_port, interval);

	if (interval > pool_config->wd_heartbeat_deadtime)
		return WD_NG;
	else
		return WD_OK;
}
Beispiel #3
0
int
is_wd_lifecheck_ready(void)
{
	int rtn = WD_OK;
	WdInfo * p = WD_List;
	int i = 0;

	while (p->status != WD_END)
	{
		/* query mode */
		if (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY))
		{
			if (wd_ping_pgpool(p) == WD_NG)
			{
				ereport(DEBUG1,
					(errmsg("watchdog checking life check is ready"),
						errdetail("pgpool:%d at \"%s:%d\" has not started yet",
							   i, p->hostname, p->pgpool_port)));
				rtn = WD_NG;
			}
		}
		/* heartbeat mode */
		else if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT))
		{
			if (p == WD_List)
			{
				p++;
				i++;
				continue;
			}

			if (!WD_TIME_ISSET(p->hb_last_recv_time) ||
			    !WD_TIME_ISSET(p->hb_send_time))
			{
				ereport(DEBUG1,
					(errmsg("watchdog checking life check is ready"),
						errdetail("pgpool:%d at \"%s:%d\" has not send the heartbeat signal yet",
							   i, p->hostname, p->pgpool_port)));
				rtn = WD_NG;
			}
		}
		/* otherwise */
		else
		{
			ereport(ERROR,
				(errmsg("checking if watchdog is ready, unkown watchdog mode \"%s\"",
							pool_config->wd_lifecheck_method)));
		}

		p ++;
		i ++;
	}

	return rtn;
}
Beispiel #4
0
int
is_wd_lifecheck_ready(void)
{
	int rtn = WD_OK;
	WdInfo * p = WD_List;
	int i = 0;

	while (p->status != WD_END)
	{
		/* query mode */
		if (!strcmp(pool_config->wd_lifecheck_method, MODE_QUERY))
		{
			if (wd_ping_pgpool(p) == WD_NG)
			{
				pool_debug("is_wd_lifecheck_ready: pgpool %d (%s:%d) has not started yet",
				           i, p->hostname, p->pgpool_port);
				rtn = WD_NG;
			}
		}
		/* heartbeat mode */
		else if (!strcmp(pool_config->wd_lifecheck_method, MODE_HEARTBEAT))
		{
			if (p == WD_List)
			{
				p++;
				i++;
				continue;
			}

			if (!WD_TIME_ISSET(p->hb_last_recv_time) ||
			    !WD_TIME_ISSET(p->hb_send_time))
			{
				pool_debug("is_wd_lifecheck_ready: pgpool %d (%s:%d) has not send the heartbeat signal yet",
				           i, p->hostname, p->pgpool_port);
				rtn = WD_NG;
			}
		}
		/* otherwise */
		else
		{
			pool_error("is_wd_lifecheck_ready: unkown watchdog mode %s",
			           pool_config->wd_lifecheck_method);
			return WD_NG;
		}

		p ++;
		i ++;
	}

	return rtn;
}
pid_t wd_hb_receiver(int fork_wait_time, WdHbIf hb_if)
{
	int sock;
	pid_t pid = 0;
	WdHbPacket pkt;
	struct timeval tv;
	char from[WD_MAX_HOST_NAMELEN];
	char buf[(MD5_PASSWD_LEN+1)*2];
	char pack_str[WD_MAX_PACKET_STRING];
	int pack_str_len;

	WdInfo * p;

	pid = fork();
	if (pid != 0)
	{
		if (pid == -1)
			pool_error("wd_hb_receiver: fork() failed.");

		return pid;
	}

	if (fork_wait_time > 0)
	{
		sleep(fork_wait_time);
	}

	myargv = save_ps_display_args(myargc, myargv);

	POOL_SETMASK(&UnBlockSig);

	signal(SIGTERM, hb_receiver_exit);
	signal(SIGINT, hb_receiver_exit);
	signal(SIGQUIT, hb_receiver_exit);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGPIPE, SIG_IGN);
	signal(SIGALRM, SIG_IGN);

	init_ps_display("", "", "", "");

	if ( (sock = wd_create_hb_recv_socket(hb_if)) < 0)
	{
		pool_error("wd_hb_receiver: socket create failed");
		hb_receiver_exit(SIGTERM);
	}

	set_ps_display("heartbeat receiver", false);

	for(;;)
	{
		if (wd_hb_recv(sock, &pkt) == WD_OK)
		{
			/* authentication */
			if (strlen(pool_config->wd_authkey))
			{
				/* calculate hash from packet */
				pack_str_len = packet_to_string_hb(pkt, pack_str, sizeof(pack_str));
				wd_calc_hash(pack_str, pack_str_len, buf);

				if (strcmp(pkt.hash, buf))
				{
					pool_log("wd_hb_receiver: authentication failed");
					continue;
				}
			}

			/* get current time */
			gettimeofday(&tv, NULL);

			/* who send this packet? */
			strlcpy(from, pkt.from, sizeof(from));

			p = WD_List;
			while (p->status != WD_END)
			{
				if (!strcmp(p->hostname, from))
				{
					/* this is the first packet or the latest packet */
					if (!WD_TIME_ISSET(p->hb_send_time) ||
					    WD_TIME_BEFORE(p->hb_send_time, pkt.send_time))
					{
						pool_debug("wd_hb_receiver: received heartbeat signal from %s", from);
						p->hb_send_time = pkt.send_time;
						p->hb_last_recv_time = tv;
					}
					break;
				}
				p++;
			}
		}
	}

	return pid;
}
Beispiel #6
0
/* fork heartbeat receiver child */
pid_t
wd_hb_receiver(int fork_wait_time, WdHbIf *hb_if)
{
	int sock;
	pid_t pid = 0;
	WdHbPacket pkt;
	struct timeval tv;
	char from[WD_MAX_HOST_NAMELEN];
	int from_pgpool_port;
	char buf[(MD5_PASSWD_LEN+1)*2];
	char pack_str[WD_MAX_PACKET_STRING];
	int pack_str_len;
	sigjmp_buf	local_sigjmp_buf;


	WdInfo * p;

	pid = fork();
	if (pid != 0)
	{
		if (pid == -1)
			ereport(PANIC,
					(errmsg("failed to fork a heartbeat receiver child")));
		return pid;
	}

	on_exit_reset();
	processType = PT_HB_RECEIVER;

	if (fork_wait_time > 0)
	{
		sleep(fork_wait_time);
	}

	POOL_SETMASK(&UnBlockSig);

	signal(SIGTERM, hb_receiver_exit);
	signal(SIGINT, hb_receiver_exit);
	signal(SIGQUIT, hb_receiver_exit);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGUSR1, SIG_IGN);
	signal(SIGUSR2, SIG_IGN);
	signal(SIGPIPE, SIG_IGN);
	signal(SIGALRM, SIG_IGN);

	init_ps_display("", "", "", "");
	/* Create per loop iteration memory context */
	ProcessLoopContext = AllocSetContextCreate(TopMemoryContext,
											   "wdhb_hb_receiver",
											   ALLOCSET_DEFAULT_MINSIZE,
											   ALLOCSET_DEFAULT_INITSIZE,
											   ALLOCSET_DEFAULT_MAXSIZE);
	
	MemoryContextSwitchTo(TopMemoryContext);

	sock = wd_create_hb_recv_socket(hb_if);

	set_ps_display("heartbeat receiver", false);

	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
	{
		/* Since not using PG_TRY, must reset error stack by hand */
		error_context_stack = NULL;
		
		EmitErrorReport();
		MemoryContextSwitchTo(TopMemoryContext);
		FlushErrorState();
	}
	
	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;

	for(;;)
	{
		MemoryContextSwitchTo(ProcessLoopContext);
		MemoryContextResetAndDeleteChildren(ProcessLoopContext);

		/* receive heartbeat signal */
		wd_hb_recv(sock, &pkt);
			/* authentication */
		if (strlen(pool_config->wd_authkey))
		{
			/* calculate hash from packet */
			pack_str_len = packet_to_string_hb(&pkt, pack_str, sizeof(pack_str));
			wd_calc_hash(pack_str, pack_str_len, buf);

			if (strcmp(pkt.hash, buf))
				ereport(ERROR,
					(errmsg("watchdog heartbeat receive"),
						 errdetail("authentication failed")));
		}

		/* get current time */
		gettimeofday(&tv, NULL);

		/* who send this packet? */
		strlcpy(from, pkt.from, sizeof(from));
		from_pgpool_port = pkt.from_pgpool_port;

		p = WD_List;
		while (p->status != WD_END)
		{
			if (!strcmp(p->hostname, from) && p->pgpool_port == from_pgpool_port)
			{
				/* ignore the packet from down pgpool */
				if (pkt.status == WD_DOWN)
				{
					ereport(DEBUG1,
						(errmsg("watchdog heartbeat: received heartbeat signal from \"%s:%d\" whose status is down. ignored",
									from, from_pgpool_port)));
					break;
				}

				/* this is the first packet or the latest packet */
				if (!WD_TIME_ISSET(p->hb_send_time) ||
					WD_TIME_BEFORE(p->hb_send_time, pkt.send_time))
				{
					ereport(DEBUG1,
							(errmsg("watchdog heartbeat: received heartbeat signal from \"%s:%d\"",
									from, from_pgpool_port)));

					p->hb_send_time = pkt.send_time;
					p->hb_last_recv_time = tv;
				}
				else
				{
					ereport(DEBUG1,
							(errmsg("watchdog heartbeat: received heartbeat signal is older than the latest, ignored")));
				}
				break;
			}
			p++;
		}

	}

	return pid;
}