From 7e99548842b534199dd6da8002088e510347864b Mon Sep 17 00:00:00 2001 From: Bart Van Der Meerssche Date: Sat, 12 Feb 2011 19:34:10 +0100 Subject: [PATCH] [luad] add an Erlang-style supervisior to the daemon --- mote/v2/openwrt/package/flukso/src/luad.c | 75 ++++++++++++++++++++--- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/mote/v2/openwrt/package/flukso/src/luad.c b/mote/v2/openwrt/package/flukso/src/luad.c index a7effd2..5c52095 100644 --- a/mote/v2/openwrt/package/flukso/src/luad.c +++ b/mote/v2/openwrt/package/flukso/src/luad.c @@ -36,6 +36,9 @@ #define DAEMON_VARRUN "/var/run" +#define SUP_ALLOWED_RESTARTS 10 +#define SUP_MAX_SECONDS 60 + #include #include #include @@ -44,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -64,6 +68,42 @@ #include #endif +struct restart_s { + int i; + time_t time[SUP_ALLOWED_RESTARTS]; +}; + +static void restart_init(struct restart_s *restart) { + restart->i = 0; + + int i; + for (i = 0; i < SUP_ALLOWED_RESTARTS; i++) { + restart->time[i] = 0; + } +} + +static void restart_add(struct restart_s *restart, time_t new_restart) { + restart->time[restart->i++] = new_restart; + restart->i %= SUP_ALLOWED_RESTARTS; +} + +static int restart_max(struct restart_s *restart) { + int i, total; + + for (i = 0; i < SUP_ALLOWED_RESTARTS; i++) { + if (restart->time[i] > time(NULL) - SUP_MAX_SECONDS) { + total++; + } + } + + if (total == SUP_ALLOWED_RESTARTS) { + return 1; + } + else { + return 0; + } +} + static void sigterm(int signo) { daemon_log(LOG_INFO, "Caught a SIGTERM. Exiting... "); @@ -292,19 +332,34 @@ int main(int argc, char *argv[]) daemon_retval_send(0); daemon_log(LOG_INFO, "Sucessfully started with DEAMON=%s and DAEMON_PATH=%s", daemon_log_ident, runtime_path); - /* Create a new Lua environment */ - L = luaL_newstate(); - /* And load the standard libraries into the Lua environment */ - luaL_openlibs(L); /* Derive the Lua daemon path from the C daemon one */ asprintf(&luad_path, "%s%s", (const char *)argv[0], ".lua"); - /* Tunnel through the wormhole into Lua neverland. This call should never return. */ - if (luaL_dofile(L, (const char *)luad_path)) { - daemon_log(LOG_ERR, "Lua returned with error message: %s", lua_tostring(L,-1)); - } - /* Clean up the Lua state */ - lua_close(L); + /* Erlang-style supervisor */ + struct restart_s restart; + restart_init(&restart); + + while(1) { + /* Stop when allowed number of restarts have occurred in specified time window */ + if (restart_max(&restart)) { + daemon_log(LOG_ERR, "%d restarts within a %d sec window", SUP_ALLOWED_RESTARTS, SUP_MAX_SECONDS); + break; + } + + /* Create a new Lua environment */ + L = luaL_newstate(); + /* And load the standard libraries into the Lua environment */ + luaL_openlibs(L); + /* Tunnel through the wormhole into Lua neverland. This call should never return. */ + if (luaL_dofile(L, (const char *)luad_path)) { + daemon_log(LOG_ERR, "%s", lua_tostring(L,-1)); + } + /* Clean up the Lua state */ + lua_close(L); + /* Wait for one second before restarting the Lua daemon */ + sleep(1); + restart_add(&restart, time(NULL)); + } /* Do a cleanup */ finish: