diff options
-rw-r--r-- | hbeat.c | 122 | ||||
-rw-r--r-- | hbeat.h | 9 | ||||
-rw-r--r-- | hbeat_test.c | 24 |
3 files changed, 155 insertions, 0 deletions
@@ -0,0 +1,122 @@ +/* + * hbeat.c -- + * + * Simple heartbeating. + * + */ + +#include <string.h> +#include <stdlib.h> +#include <sys/types.h> +#include <time.h> + +#include "btime.h" +#include "hbeat.h" + + +struct hbeat_s { + char *host; + int max_timeout; + enum {HOST_ALIVE, HOST_QUIET, HOST_TIMEOUT, HOST_REBOOT} 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; + + /* User disabled heart beating */ + if (!hbeatp->max_timeout) { + return 1; + } + + hbeat = btime(hbeatp->host); + current_time = time(NULL); + + if (!hbeat && (hbeatp->rhost_state == HOST_QUIET)) { + if (current_time - hbeatp->start_quiet_time + > hbeatp->max_timeout) { + hbeatp->rhost_state = HOST_TIMEOUT; + return 0; + } + } else { + hbeatp->rhost_state = HOST_QUIET; + hbeatp->start_quiet_time = time(NULL); + } + + if (hbeat) { + if (hbeatp->last_rhost_btime == 0) { + hbeatp->last_rhost_btime = hbeat; + hbeatp->rhost_state = HOST_ALIVE; + hbeatp->start_quiet_time = 0; + } + + if (abs(hbeat - hbeatp->last_rhost_btime) > 5) { + hbeatp->rhost_state = HOST_REBOOT; + return 0; + } + } + + return 1; +} @@ -0,0 +1,9 @@ +/* + * hbeat.h + */ + +typedef void * hbeat_t; + +extern hbeat_t hbeat_init(const char *host, int max_timeout); +void hbeat_free(hbeat_t hbh); +unsigned int hbeat(hbeat_t hbh); diff --git a/hbeat_test.c b/hbeat_test.c new file mode 100644 index 0000000..8ea00ee --- /dev/null +++ b/hbeat_test.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include "hbeat.h" + +int +main(void) +{ + hbeat_t hb; + int i; + int timeout_max = 10; + + hb = hbeat_init("link-13", timeout_max); + + for (i = 0; i < 10; i++) { + printf("hbeat() = %d\n", hbeat(hb)); + sleep(1); + } + + hbeat_free(hb); + + return 0; +} + + + |