diff options
Diffstat (limited to 'src/backend/postmaster/syslogger.c')
-rw-r--r-- | src/backend/postmaster/syslogger.c | 280 |
1 files changed, 116 insertions, 164 deletions
diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index d9d042f5628..08efe74cc91 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -39,7 +39,6 @@ #include "pgstat.h" #include "pgtime.h" #include "port/pg_bitutils.h" -#include "postmaster/fork_process.h" #include "postmaster/interrupt.h" #include "postmaster/postmaster.h" #include "postmaster/syslogger.h" @@ -50,6 +49,7 @@ #include "storage/pg_shmem.h" #include "tcop/tcopprot.h" #include "utils/guc.h" +#include "utils/memutils.h" #include "utils/ps_status.h" /* @@ -133,10 +133,7 @@ static volatile sig_atomic_t rotation_requested = false; #ifdef EXEC_BACKEND static int syslogger_fdget(FILE *file); static FILE *syslogger_fdopen(int fd); -static pid_t syslogger_forkexec(void); -static void syslogger_parseArgs(int argc, char *argv[]); #endif -NON_EXEC_STATIC void SysLoggerMain(int argc, char *argv[]) pg_attribute_noreturn(); static void process_pipe_input(char *logbuffer, int *bytes_in_logbuffer); static void flush_pipe_input(char *logbuffer, int *bytes_in_logbuffer); static FILE *logfile_open(const char *filename, const char *mode, @@ -155,13 +152,19 @@ static void set_next_rotation_time(void); static void sigUsr1Handler(SIGNAL_ARGS); static void update_metainfo_datafile(void); +typedef struct +{ + int syslogFile; + int csvlogFile; + int jsonlogFile; +} SysloggerStartupData; /* * Main entry point for syslogger process * argc/argv parameters are valid only in EXEC_BACKEND case. */ -NON_EXEC_STATIC void -SysLoggerMain(int argc, char *argv[]) +void +SysLoggerMain(char *startup_data, size_t startup_data_len) { #ifndef WIN32 char logbuffer[READ_BUF_SIZE]; @@ -173,11 +176,37 @@ SysLoggerMain(int argc, char *argv[]) pg_time_t now; WaitEventSet *wes; - now = MyStartTime; - + /* + * Re-open the error output files that were opened by SysLogger_Start(). + * + * We expect this will always succeed, which is too optimistic, but if it + * fails there's not a lot we can do to report the problem anyway. As + * coded, we'll just crash on a null pointer dereference after failure... + */ #ifdef EXEC_BACKEND - syslogger_parseArgs(argc, argv); -#endif /* EXEC_BACKEND */ + { + SysloggerStartupData *slsdata = (SysloggerStartupData *) startup_data; + + Assert(startup_data_len == sizeof(*slsdata)); + syslogFile = syslogger_fdopen(slsdata->syslogFile); + csvlogFile = syslogger_fdopen(slsdata->csvlogFile); + jsonlogFile = syslogger_fdopen(slsdata->jsonlogFile); + } +#else + Assert(startup_data_len == 0); +#endif + + /* + * Now that we're done reading the startup data, release postmaster's + * working memory context. + */ + if (PostmasterContext) + { + MemoryContextDelete(PostmasterContext); + PostmasterContext = NULL; + } + + now = MyStartTime; MyBackendType = B_LOGGER; init_ps_display(NULL); @@ -567,6 +596,9 @@ SysLogger_Start(void) { pid_t sysloggerPid; char *filename; +#ifdef EXEC_BACKEND + SysloggerStartupData startup_data; +#endif /* EXEC_BACKEND */ if (!Logging_collector) return 0; @@ -666,112 +698,95 @@ SysLogger_Start(void) } #ifdef EXEC_BACKEND - switch ((sysloggerPid = syslogger_forkexec())) + startup_data.syslogFile = syslogger_fdget(syslogFile); + startup_data.csvlogFile = syslogger_fdget(csvlogFile); + startup_data.jsonlogFile = syslogger_fdget(jsonlogFile); + sysloggerPid = postmaster_child_launch(B_LOGGER, (char *) &startup_data, sizeof(startup_data), NULL); #else - switch ((sysloggerPid = fork_process())) -#endif - { - case -1: - ereport(LOG, - (errmsg("could not fork system logger: %m"))); - return 0; - -#ifndef EXEC_BACKEND - case 0: - /* in postmaster child ... */ - InitPostmasterChild(); - - /* Close the postmaster's sockets */ - ClosePostmasterPorts(true); - - /* Drop our connection to postmaster's shared memory, as well */ - dsm_detach_all(); - PGSharedMemoryDetach(); + sysloggerPid = postmaster_child_launch(B_LOGGER, NULL, 0, NULL); +#endif /* EXEC_BACKEND */ - /* do the work */ - SysLoggerMain(0, NULL); - break; -#endif + if (sysloggerPid == -1) + { + ereport(LOG, + (errmsg("could not fork system logger: %m"))); + return 0; + } - default: - /* success, in postmaster */ + /* success, in postmaster */ - /* now we redirect stderr, if not done already */ - if (!redirection_done) - { + /* now we redirect stderr, if not done already */ + if (!redirection_done) + { #ifdef WIN32 - int fd; + int fd; #endif - /* - * Leave a breadcrumb trail when redirecting, in case the user - * forgets that redirection is active and looks only at the - * original stderr target file. - */ - ereport(LOG, - (errmsg("redirecting log output to logging collector process"), - errhint("Future log output will appear in directory \"%s\".", - Log_directory))); + /* + * Leave a breadcrumb trail when redirecting, in case the user forgets + * that redirection is active and looks only at the original stderr + * target file. + */ + ereport(LOG, + (errmsg("redirecting log output to logging collector process"), + errhint("Future log output will appear in directory \"%s\".", + Log_directory))); #ifndef WIN32 - fflush(stdout); - if (dup2(syslogPipe[1], STDOUT_FILENO) < 0) - ereport(FATAL, - (errcode_for_file_access(), - errmsg("could not redirect stdout: %m"))); - fflush(stderr); - if (dup2(syslogPipe[1], STDERR_FILENO) < 0) - ereport(FATAL, - (errcode_for_file_access(), - errmsg("could not redirect stderr: %m"))); - /* Now we are done with the write end of the pipe. */ - close(syslogPipe[1]); - syslogPipe[1] = -1; + fflush(stdout); + if (dup2(syslogPipe[1], STDOUT_FILENO) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not redirect stdout: %m"))); + fflush(stderr); + if (dup2(syslogPipe[1], STDERR_FILENO) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not redirect stderr: %m"))); + /* Now we are done with the write end of the pipe. */ + close(syslogPipe[1]); + syslogPipe[1] = -1; #else - /* - * open the pipe in binary mode and make sure stderr is binary - * after it's been dup'ed into, to avoid disturbing the pipe - * chunking protocol. - */ - fflush(stderr); - fd = _open_osfhandle((intptr_t) syslogPipe[1], - _O_APPEND | _O_BINARY); - if (dup2(fd, STDERR_FILENO) < 0) - ereport(FATAL, - (errcode_for_file_access(), - errmsg("could not redirect stderr: %m"))); - close(fd); - _setmode(STDERR_FILENO, _O_BINARY); + /* + * open the pipe in binary mode and make sure stderr is binary after + * it's been dup'ed into, to avoid disturbing the pipe chunking + * protocol. + */ + fflush(stderr); + fd = _open_osfhandle((intptr_t) syslogPipe[1], + _O_APPEND | _O_BINARY); + if (dup2(fd, STDERR_FILENO) < 0) + ereport(FATAL, + (errcode_for_file_access(), + errmsg("could not redirect stderr: %m"))); + close(fd); + _setmode(STDERR_FILENO, _O_BINARY); - /* - * Now we are done with the write end of the pipe. - * CloseHandle() must not be called because the preceding - * close() closes the underlying handle. - */ - syslogPipe[1] = 0; + /* + * Now we are done with the write end of the pipe. CloseHandle() must + * not be called because the preceding close() closes the underlying + * handle. + */ + syslogPipe[1] = 0; #endif - redirection_done = true; - } - - /* postmaster will never write the file(s); close 'em */ - fclose(syslogFile); - syslogFile = NULL; - if (csvlogFile != NULL) - { - fclose(csvlogFile); - csvlogFile = NULL; - } - if (jsonlogFile != NULL) - { - fclose(jsonlogFile); - jsonlogFile = NULL; - } - return (int) sysloggerPid; + redirection_done = true; } - /* we should never reach here */ - return 0; + /* postmaster will never write the file(s); close 'em */ + fclose(syslogFile); + syslogFile = NULL; + if (csvlogFile != NULL) + { + fclose(csvlogFile); + csvlogFile = NULL; + } + if (jsonlogFile != NULL) + { + fclose(jsonlogFile); + jsonlogFile = NULL; + } + return (int) sysloggerPid; } @@ -830,69 +845,6 @@ syslogger_fdopen(int fd) return file; } - -/* - * syslogger_forkexec() - - * - * Format up the arglist for, then fork and exec, a syslogger process - */ -static pid_t -syslogger_forkexec(void) -{ - char *av[10]; - int ac = 0; - char filenobuf[32]; - char csvfilenobuf[32]; - char jsonfilenobuf[32]; - - av[ac++] = "postgres"; - av[ac++] = "--forklog"; - av[ac++] = NULL; /* filled in by postmaster_forkexec */ - - /* static variables (those not passed by write_backend_variables) */ - snprintf(filenobuf, sizeof(filenobuf), "%d", - syslogger_fdget(syslogFile)); - av[ac++] = filenobuf; - snprintf(csvfilenobuf, sizeof(csvfilenobuf), "%d", - syslogger_fdget(csvlogFile)); - av[ac++] = csvfilenobuf; - snprintf(jsonfilenobuf, sizeof(jsonfilenobuf), "%d", - syslogger_fdget(jsonlogFile)); - av[ac++] = jsonfilenobuf; - - av[ac] = NULL; - Assert(ac < lengthof(av)); - - return postmaster_forkexec(ac, av); -} - -/* - * syslogger_parseArgs() - - * - * Extract data from the arglist for exec'ed syslogger process - */ -static void -syslogger_parseArgs(int argc, char *argv[]) -{ - int fd; - - Assert(argc == 6); - argv += 3; - - /* - * Re-open the error output files that were opened by SysLogger_Start(). - * - * We expect this will always succeed, which is too optimistic, but if it - * fails there's not a lot we can do to report the problem anyway. As - * coded, we'll just crash on a null pointer dereference after failure... - */ - fd = atoi(*argv++); - syslogFile = syslogger_fdopen(fd); - fd = atoi(*argv++); - csvlogFile = syslogger_fdopen(fd); - fd = atoi(*argv++); - jsonlogFile = syslogger_fdopen(fd); -} #endif /* EXEC_BACKEND */ |