/* * 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; }
/* * 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; }
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; }
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; }
/* 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; }