]> git.ipfire.org Git - thirdparty/chrony.git/commitdiff
Wait in foreground process until daemon is fully initialized
authorMiroslav Lichvar <mlichvar@redhat.com>
Fri, 26 Aug 2011 12:47:30 +0000 (14:47 +0200)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 26 Aug 2011 16:31:26 +0000 (18:31 +0200)
Exit when all sockets are ready and initstepslew command and rtc step
are completed. Also, in case of a fatal error, print the error message
and exit with a non-zero status.

logging.c
logging.h
main.c

index 63424218e4a1e2bfacebc74fe88eb9199dcc42c7..25378e81b472a47a730ec3a2dcad78ea95da5812 100644 (file)
--- a/logging.c
+++ b/logging.c
@@ -41,6 +41,8 @@ static int initialised = 0;
 
 static int system_log = 0;
 
+static int parent_fd = 0;
+
 static time_t last_limited = 0;
 
 #ifdef WINNT
@@ -154,6 +156,9 @@ LOG_Fatal_Function(LOG_Facility facility, const char *format, ...)
   } else {
     fprintf(stderr, "Fatal error : %s\n", buf);
   }
+  if (parent_fd) {
+    write(parent_fd, buf, strlen(buf) + 1);
+  }
 #endif
 
   MAI_CleanupAndExit();
@@ -196,6 +201,23 @@ LOG_OpenSystemLog(void)
 
 /* ================================================== */
 
+void
+LOG_SetParentFd(int fd)
+{
+  parent_fd = fd;
+}
+
+/* ================================================== */
+
+void
+LOG_CloseParentFd()
+{
+  if (parent_fd > 0)
+    close(parent_fd);
+}
+
+/* ================================================== */
+
 int
 LOG_RateLimited(void)
 {
index 5038cc8c07462887f14c8990bcdb81801476c2ed..b927eaab486e2d2168f89260f5fbeaea7803bd7c 100644 (file)
--- a/logging.h
+++ b/logging.h
@@ -85,6 +85,12 @@ extern void LOG_Position(const char *filename, int line_number, const char *func
 /* Log messages to syslog instead of stderr */
 extern void LOG_OpenSystemLog(void);
 
+/* Send fatal message also to the foreground process */
+extern void LOG_SetParentFd(int fd);
+
+/* Close the pipe to the foreground process so it can exit */
+extern void LOG_CloseParentFd(void);
+
 /* Return zero once per 10 seconds */
 extern int LOG_RateLimited(void);
 
diff --git a/main.c b/main.c
index e68846e160805545244300e66950e2abc2c380de..3bf02aac6c9167f8696fdf9d1c69af6b5fc65241 100644 (file)
--- a/main.c
+++ b/main.c
@@ -124,6 +124,8 @@ signal_cleanup(int x)
 static void
 post_acquire_hook(void *anything)
 {
+  /* Close the pipe to the foreground process so it can exit */
+  LOG_CloseParentFd();
 
   CNF_AddSources();
   CNF_AddBroadcasts();
@@ -214,7 +216,13 @@ go_daemon(void)
 
 #else
 
-  int pid, fd;
+  int pid, fd, pipefd[2];
+
+  /* Create pipe which will the daemon use to notify the grandparent
+     when it's initialised or send an error message */
+  if (pipe(pipefd)) {
+    LOG(LOGS_ERR, LOGF_Logging, "Could not detach, pipe failed : %s", strerror(errno));
+  }
 
   /* Does this preserve existing signal handlers? */
   pid = fork();
@@ -222,8 +230,22 @@ go_daemon(void)
   if (pid < 0) {
     LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
   } else if (pid > 0) {
-    exit(0); /* In the 'grandparent' */
+    /* In the 'grandparent' */
+    char message[1024];
+    int r;
+
+    close(pipefd[1]);
+    r = read(pipefd[0], message, sizeof (message));
+    if (r) {
+      if (r > 0) {
+        /* Print the error message from the child */
+        fprintf(stderr, "%.1024s\n", message);
+      }
+      exit(1);
+    } else
+      exit(0);
   } else {
+    close(pipefd[0]);
 
     setsid();
 
@@ -237,13 +259,17 @@ go_daemon(void)
     } else {
       /* In the child we want to leave running as the daemon */
 
-      /* Don't keep stdin/out/err from before. */
+      /* Don't keep stdin/out/err from before. But don't close
+         the parent pipe yet. */
       for (fd=0; fd<1024; fd++) {
-        close(fd);
+        if (fd != pipefd[1])
+          close(fd);
       }
 
       /* Change current directory to / */
       chdir("/");
+
+      LOG_SetParentFd(pipefd[1]);
     }
   }
 
@@ -331,7 +357,6 @@ int main
   if (maybe_another_chronyd_running(&other_pid)) {
     LOG_FATAL(LOGF_Main, "Another chronyd may already be running (pid=%d), check lockfile (%s)",
               other_pid, CNF_GetPidFile());
-    exit(1);
   }
 
   /* Write our lockfile to prevent other chronyds running.  This has *GOT* to