/* * hbeat.c -- * * Simple heartbeating. * */ #include #include #include #include #include "btime.h" #include "hbeat.h" struct hbeat_s { char *host; int max_timeout; hbeat_state_t rhost_state; unsigned int last_rhost_btime; time_t start_quiet_time; }; /* * hbeat_init -- * * Init a heartbeat to host, with max_timeout as supplied. * * Returns: * A hbeat handle, or NULL on error; */ hbeat_t hbeat_init(const char *host, int max_timeout) { struct hbeat_s *hbeatp; hbeatp = malloc(sizeof *hbeatp); if (!hbeatp) { return NULL; } hbeatp->host = strdup(host); hbeatp->max_timeout = max_timeout; hbeatp->rhost_state = HOST_ALIVE; hbeatp->last_rhost_btime = 0; hbeatp->start_quiet_time = 0; return hbeatp; } /* * hbeat_free -- * * Free a hbeat handle. */ void hbeat_free(hbeat_t hbh) { struct hbeat_s *hbeatp = hbh; free(hbeatp->host); free(hbeatp); } /* * hbeat -- * * Attempt to contact host in the hbeat handle, run the hbeat * "state machine" to decide if we the host is still "alive." * * Returns: * 1 if host has been active or responded withing max_timeout secs. * 0 if host is dead, no response for > max_timeout secs. */ unsigned int hbeat(hbeat_t hbh) { struct hbeat_s *hbeatp = hbh; unsigned int hbeat; time_t current_time; int retval; /* User disabled heart beating */ if (!hbeatp->max_timeout) { hbeatp->rhost_state = HOST_HBEAT_DISABLED; return 1; } hbeat = btime(hbeatp->host); current_time = time(NULL); if (!hbeat) { switch (hbeatp->rhost_state) { case HOST_ALIVE: hbeatp->rhost_state = HOST_QUIET; hbeatp->start_quiet_time = time(NULL); retval = 1; break; case HOST_QUIET: if (current_time - hbeatp->start_quiet_time > hbeatp->max_timeout) { hbeatp->rhost_state = HOST_TIMEOUT; retval = 0; } else { retval = 1; } break; case HOST_TIMEOUT: case HOST_REBOOT: retval = 0; break; case HOST_HBEAT_DISABLED: retval = 1; break; } } if (hbeat) { if (hbeatp->rhost_state == HOST_REBOOT) { retval = 0; } else { hbeatp->last_rhost_btime = hbeat; hbeatp->rhost_state = HOST_ALIVE; hbeatp->start_quiet_time = 0; retval = 1; if (abs(hbeat - hbeatp->last_rhost_btime) > 5) { hbeatp->rhost_state = HOST_REBOOT; retval = 0; } } } return retval; } hbeat_state_t hbeat_getstate(hbeat_t hbh) { return ((struct hbeat_s *)hbh)->rhost_state; } void hbeat_setstate(hbeat_t hbh, hbeat_state_t state) { ((struct hbeat_s *)hbh)->rhost_state = state; return; }