Wait in foreground process until daemon is fully initialized

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.
This commit is contained in:
Miroslav Lichvar 2011-08-26 14:47:30 +02:00
parent 7fb50d9a3e
commit 1d2a0856b4
3 changed files with 58 additions and 5 deletions

View file

@ -41,6 +41,8 @@ static int initialised = 0;
static int system_log = 0; static int system_log = 0;
static int parent_fd = 0;
static time_t last_limited = 0; static time_t last_limited = 0;
#ifdef WINNT #ifdef WINNT
@ -154,6 +156,9 @@ LOG_Fatal_Function(LOG_Facility facility, const char *format, ...)
} else { } else {
fprintf(stderr, "Fatal error : %s\n", buf); fprintf(stderr, "Fatal error : %s\n", buf);
} }
if (parent_fd) {
write(parent_fd, buf, strlen(buf) + 1);
}
#endif #endif
MAI_CleanupAndExit(); 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 int
LOG_RateLimited(void) LOG_RateLimited(void)
{ {

View file

@ -85,6 +85,12 @@ extern void LOG_Position(const char *filename, int line_number, const char *func
/* Log messages to syslog instead of stderr */ /* Log messages to syslog instead of stderr */
extern void LOG_OpenSystemLog(void); 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 */ /* Return zero once per 10 seconds */
extern int LOG_RateLimited(void); extern int LOG_RateLimited(void);

35
main.c
View file

@ -124,6 +124,8 @@ signal_cleanup(int x)
static void static void
post_acquire_hook(void *anything) post_acquire_hook(void *anything)
{ {
/* Close the pipe to the foreground process so it can exit */
LOG_CloseParentFd();
CNF_AddSources(); CNF_AddSources();
CNF_AddBroadcasts(); CNF_AddBroadcasts();
@ -214,7 +216,13 @@ go_daemon(void)
#else #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? */ /* Does this preserve existing signal handlers? */
pid = fork(); pid = fork();
@ -222,8 +230,22 @@ go_daemon(void)
if (pid < 0) { if (pid < 0) {
LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno)); LOG(LOGS_ERR, LOGF_Logging, "Could not detach, fork failed : %s", strerror(errno));
} else if (pid > 0) { } 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 { } else {
close(pipefd[0]);
setsid(); setsid();
@ -237,13 +259,17 @@ go_daemon(void)
} else { } else {
/* In the child we want to leave running as the daemon */ /* 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++) { for (fd=0; fd<1024; fd++) {
close(fd); if (fd != pipefd[1])
close(fd);
} }
/* Change current directory to / */ /* Change current directory to / */
chdir("/"); chdir("/");
LOG_SetParentFd(pipefd[1]);
} }
} }
@ -331,7 +357,6 @@ int main
if (maybe_another_chronyd_running(&other_pid)) { if (maybe_another_chronyd_running(&other_pid)) {
LOG_FATAL(LOGF_Main, "Another chronyd may already be running (pid=%d), check lockfile (%s)", LOG_FATAL(LOGF_Main, "Another chronyd may already be running (pid=%d), check lockfile (%s)",
other_pid, CNF_GetPidFile()); other_pid, CNF_GetPidFile());
exit(1);
} }
/* Write our lockfile to prevent other chronyds running. This has *GOT* to /* Write our lockfile to prevent other chronyds running. This has *GOT* to