diff --git a/lib/api/actions/reload.c b/lib/api/actions/reload.c index e0ea4392a..02431e16d 100644 --- a/lib/api/actions/reload.c +++ b/lib/api/actions/reload.c @@ -1,4 +1,4 @@ -/** The "restart" API ressource. +/** The "restart" API action. * * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC @@ -22,11 +22,64 @@ #include "plugin.h" #include "api.h" +#include "super_node.h" + +#include "log.h" + +static char *config; + +void api_restart_handler() +{ + int ret; + + char *argv[] = { "villas-node", config, NULL }; + + ret = execvpe("/proc/self/exe", argv, environ); + if (ret) + serror("Failed to restart"); +} -/** @todo not implemented yet */ static int api_restart(struct api_action *h, json_t *args, json_t **resp, struct api_session *s) { - return -1; + int ret; + json_error_t err; + + /* If no config is provided via request, we will use the previous one */ + config = strdup(s->api->super_node->uri); + + if (args) { + ret = json_unpack_ex(args, &err, 0, "{ s?: s }", "config", &config); + if (ret < 0) { + *resp = json_string("failed to parse request"); + return -1; + } + } + + /* Increment API restart counter */ + char *scnt = getenv("VILLAS_API_RESTART_COUNT"); + int cnt = scnt ? atoi(scnt) : 0; + char buf[32]; + snprintf(buf, sizeof(buf), "%d", cnt + 1); + + /* We pass some env variables to the new process */ + setenv("VILLAS_API_RESTART_COUNT", buf, 1); + setenv("VILLAS_API_RESTART_REMOTE", s->peer.ip, 1); + + *resp = json_pack("{ s: i, s: s, s: s }", + "restarts", cnt, + "config", config, + "remote", s->peer.ip + ); + + /* Register exit handler */ + ret = atexit(api_restart_handler); + if (ret) + return 0; + + /* Properly terminate current instance */ + killme(SIGTERM); + + return 0; } static struct plugin p = { diff --git a/lib/utils.c b/lib/utils.c index 38e1063e0..a94e7c45b 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -302,7 +302,7 @@ int signals_init(void (*cb)(int signal, siginfo_t *sinfo, void *ctx)) info("Initialize signals"); struct sigaction sa_quit = { - .sa_flags = SA_SIGINFO, + .sa_flags = SA_SIGINFO | SA_NODEFER, .sa_sigaction = cb };