X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=lib%2Fdaemon.c;h=5486504641b6ded5fa94dae6b5506be66a07ba0c;hb=refs%2Fheads%2Flts-1.0;hp=46c9a88e750bc554cda1c92393a6412bd7eba633;hpb=02dd3123a0e312f1d33403e744af52dd6096f12d;p=sliver-openvswitch.git diff --git a/lib/daemon.c b/lib/daemon.c index 46c9a88e7..548650464 100644 --- a/lib/daemon.c +++ b/lib/daemon.c @@ -18,8 +18,10 @@ #include "daemon.h" #include #include +#include #include #include +#include #include #include #include "command-line.h" @@ -30,20 +32,21 @@ #include "socket-util.h" #include "timeval.h" #include "util.h" - -#define THIS_MODULE VLM_daemon #include "vlog.h" -/* Should we run in the background? */ +VLOG_DEFINE_THIS_MODULE(daemon) + +/* --detach: Should we run in the background? */ static bool detach; -/* Name of pidfile (null if none). */ +/* --pidfile: Name of pidfile (null if none). */ static char *pidfile; -/* Create pidfile even if one already exists and is locked? */ +/* --overwrite-pidfile: Create pidfile even if one already exists and is + locked? */ static bool overwrite_pidfile; -/* Should we chdir to "/"? */ +/* --no-chdir: Should we chdir to "/"? */ static bool chdir_ = true; /* File descriptor used by daemonize_start() and daemonize_complete(). */ @@ -56,11 +59,11 @@ static bool monitor; /* Returns the file name that would be used for a pidfile if 'name' were * provided to set_pidfile(). The caller must free the returned string. */ char * -make_pidfile_name(const char *name) +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'. @@ -172,9 +175,9 @@ die_if_already_running(void) } } -/* If a pidfile has been configured, creates it and stores the running process' - * pid init. Ensures that the pidfile will be deleted when the process - * exits. */ +/* If a pidfile has been configured, creates it and stores the running + * process's pid in it. Ensures that the pidfile will be deleted when the + * process exits. */ static void make_pidfile(void) { @@ -323,14 +326,15 @@ 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; @@ -353,6 +357,33 @@ monitor_daemon(pid_t daemon_pid) free(s); if (should_restart(status)) { + 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) { @@ -418,6 +449,10 @@ daemonize_start(void) } make_pidfile(); + + /* Make sure that the unixctl commands for vlog get registered in a + * daemon, even before the first log message. */ + vlog_init(); } /* If daemonization is configured, then this function notifies the parent