X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdaemon.c;h=6cb553acf257fbec132819060e86b8f852620639;hb=5136ce492c414f377f7be9ae32b259abb9f76580;hp=8629114637f0df62cb2631d82145ca6b8615fbf3;hpb=ff8decf1a318b4a611cb08bb3f12833044e8a872;p=sliver-openvswitch.git diff --git a/lib/daemon.c b/lib/daemon.c index 862911463..6cb553acf 100644 --- a/lib/daemon.c +++ b/lib/daemon.c @@ -18,10 +18,13 @@ #include "daemon.h" #include #include +#include #include #include +#include #include #include +#include "command-line.h" #include "fatal-signal.h" #include "dirs.h" #include "lockfile.h" @@ -29,10 +32,10 @@ #include "socket-util.h" #include "timeval.h" #include "util.h" - -#define THIS_MODULE VLM_daemon #include "vlog.h" +VLOG_DEFINE_THIS_MODULE(daemon) + /* Should we run in the background? */ static bool detach; @@ -57,9 +60,9 @@ static bool monitor; char * make_pidfile_name(const char *name) { - return (!name ? xasprintf("%s/%s.pid", ovs_rundir, program_name) - : *name == '/' ? xstrdup(name) - : xasprintf("%s/%s", ovs_rundir, name)); + return (!name + ? xasprintf("%s/%s.pid", ovs_rundir, program_name) + : abs_file_name(ovs_rundir, name)); } /* Sets up a following call to daemonize() to create a pidfile named 'name'. @@ -322,16 +325,23 @@ should_restart(int status) static void monitor_daemon(pid_t daemon_pid) { - /* XXX Should limit the rate at which we restart the daemon. */ /* XXX Should log daemon's stderr output at startup time. */ const char *saved_program_name; + time_t last_restart; + char *status_msg; saved_program_name = program_name; program_name = xasprintf("monitor(%s)", program_name); + status_msg = xstrdup("healthy"); + last_restart = TIME_MIN; for (;;) { int retval; int status; + proctitle_set("%s: monitoring pid %lu (%s)", + saved_program_name, (unsigned long int) daemon_pid, + status_msg); + do { retval = waitpid(daemon_pid, &status, 0); } while (retval == -1 && errno == EINTR); @@ -339,25 +349,55 @@ monitor_daemon(pid_t daemon_pid) if (retval == -1) { ovs_fatal(errno, "waitpid failed"); } else if (retval == daemon_pid) { - char *status_msg = process_status_msg(status); + char *s = process_status_msg(status); + free(status_msg); + status_msg = xasprintf("pid %lu died, %s", + (unsigned long int) daemon_pid, s); + free(s); + if (should_restart(status)) { - VLOG_ERR("%s daemon died unexpectedly (%s), restarting", - saved_program_name, status_msg); - free(status_msg); + if (WCOREDUMP(status)) { + /* Disable further core dumps to save disk space. */ + struct rlimit r; + + r.rlim_cur = 0; + r.rlim_max = 0; + if (setrlimit(RLIMIT_CORE, &r) == -1) { + VLOG_WARN("failed to disable core dumps: %s", + strerror(errno)); + } + } + + /* Throttle restarts to no more than once every 10 seconds. */ + if (time(NULL) < last_restart + 10) { + VLOG_WARN("%s, waiting until 10 seconds since last " + "restart", status_msg); + for (;;) { + time_t now = time(NULL); + time_t wakeup = last_restart + 10; + if (now >= wakeup) { + break; + } + sleep(wakeup - now); + } + } + last_restart = time(NULL); + VLOG_ERR("%s, restarting", status_msg); daemon_pid = fork_and_wait_for_startup(&daemonize_fd); if (!daemon_pid) { break; } } else { - VLOG_INFO("%s daemon exited normally (%s), exiting", - saved_program_name, status_msg); + VLOG_INFO("%s, exiting", status_msg); exit(0); } } } + free(status_msg); /* Running in new daemon process. */ + proctitle_restore(); free((char *) program_name); program_name = saved_program_name; }