+ close(fd);
+ }
+}
+
+static bool
+should_restart(int status)
+{
+ if (WIFSIGNALED(status)) {
+ static const int error_signals[] = {
+ SIGABRT, SIGALRM, SIGBUS, SIGFPE, SIGILL, SIGPIPE, SIGSEGV,
+ SIGXCPU, SIGXFSZ
+ };
+
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(error_signals); i++) {
+ if (error_signals[i] == WTERMSIG(status)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+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;
+ char *status_msg;
+
+ saved_program_name = program_name;
+ program_name = xasprintf("monitor(%s)", program_name);
+ status_msg = xstrdup("healthy");
+ 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);
+
+ if (retval == -1) {
+ ovs_fatal(errno, "waitpid failed");
+ } else if (retval == daemon_pid) {
+ 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, restarting", status_msg);
+ daemon_pid = fork_and_wait_for_startup(&daemonize_fd);
+ if (!daemon_pid) {
+ break;
+ }
+ } else {
+ VLOG_INFO("%s, exiting", status_msg);
+ exit(0);