diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 2b34921e70b3eced925b605a35b9388574cb8938..7a44f074a8605579c0d2f7d3fe98c1d1bc3f0e80 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1,4 +1,4 @@ -<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.223 2009/08/04 16:08:35 tgl Exp $ --> +<!-- $PostgreSQL: pgsql/doc/src/sgml/config.sgml,v 1.224 2009/08/24 20:08:31 tgl Exp $ --> <chapter Id="runtime-config"> <title>Server Configuration</title> @@ -2588,7 +2588,37 @@ local0.* /var/log/postgresql </para> </listitem> </varlistentry> - + + <varlistentry id="guc-silent-mode" xreflabel="silent_mode"> + <term><varname>silent_mode</varname> (<type>boolean</type>)</term> + <indexterm> + <primary><varname>silent_mode</> configuration parameter</primary> + </indexterm> + <listitem> + <para> + Runs the server silently. If this parameter is set, the server + will automatically run in background and disassociate from the + controlling terminal. + This parameter can only be set at server start. + </para> + + <caution> + <para> + When this parameter is set, + the server's standard output and standard error are redirected + to the file <filename>postmaster.log</> within the data directory. + There is no provision for rotating this file, so it will grow + indefinitely unless server log output is redirected elsewhere + by other settings. It is recommended that <varname>log_destination</> + be set to <literal>syslog</> or that <varname>logging_collector</> be + enabled when using this option. Even with those measures, errors + reported early during startup may appear in + <filename>postmaster.log</> rather than the normal log destination. + </para> + </caution> + </listitem> + </varlistentry> + </variablelist> </sect2> <sect2 id="runtime-config-logging-when"> @@ -2722,26 +2752,6 @@ local0.* /var/log/postgresql </listitem> </varlistentry> - <varlistentry id="guc-silent-mode" xreflabel="silent_mode"> - <term><varname>silent_mode</varname> (<type>boolean</type>)</term> - <indexterm> - <primary><varname>silent_mode</> configuration parameter</primary> - </indexterm> - <listitem> - <para> - Runs the server silently. If this parameter is set, the server - will automatically run in background and any controlling - terminals are disassociated. - The server's standard output and standard error are redirected - to <literal>/dev/null</>, so any messages sent to them will be lost. - Unless <application>syslog</> logging is selected or - <varname>logging_collector</> is enabled, using this parameter - is discouraged because it makes it impossible to see error messages. - This parameter can only be set at server start. - </para> - </listitem> - </varlistentry> - </variablelist> <para> diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index cabd61fc0f3458f2303a5877d16b483697856651..7c96d978a0d129490e9031525b6cec089ff0316b 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.589 2009/08/24 18:09:37 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.590 2009/08/24 20:08:32 tgl Exp $ * * NOTES * @@ -191,7 +191,7 @@ static int SendStop = false; /* still more option variables */ bool EnableSSL = false; -bool SilentMode = false; /* silent mode (-S) */ +bool SilentMode = false; /* silent_mode */ int PreAuthDelay = 0; int AuthenticationTimeout = 60; @@ -744,7 +744,7 @@ PostmasterMain(int argc, char *argv[]) } /* - * Fork away from controlling terminal, if -S specified. + * Fork away from controlling terminal, if silent_mode specified. * * Must do this before we grab any interlock files, else the interlocks * will show the wrong PID. @@ -894,20 +894,6 @@ PostmasterMain(int argc, char *argv[]) */ set_max_safe_fds(); - /* - * Load configuration files for client authentication. - */ - if (!load_hba()) - { - /* - * It makes no sense continue if we fail to load the HBA file, since - * there is no way to connect to the database in this case. - */ - ereport(FATAL, - (errmsg("could not load pg_hba.conf"))); - } - load_ident(); - /* * Initialize the list of active backends. */ @@ -1023,6 +1009,20 @@ PostmasterMain(int argc, char *argv[]) */ autovac_init(); + /* + * Load configuration files for client authentication. + */ + if (!load_hba()) + { + /* + * It makes no sense to continue if we fail to load the HBA file, + * since there is no way to connect to the database in this case. + */ + ereport(FATAL, + (errmsg("could not load pg_hba.conf"))); + } + load_ident(); + /* * Remember postmaster startup time */ @@ -1204,15 +1204,46 @@ reg_reply(DNSServiceRegistrationReplyErrorType errorCode, void *context) /* - * Fork away from the controlling terminal (-S option) + * Fork away from the controlling terminal (silent_mode option) + * + * Since this requires disconnecting from stdin/stdout/stderr (in case they're + * linked to the terminal), we re-point stdin to /dev/null and stdout/stderr + * to "postmaster.log" in the data directory, where we're already chdir'd. */ static void pmdaemonize(void) { #ifndef WIN32 - int i; + const char *pmlogname = "postmaster.log"; + int dvnull; + int pmlog; pid_t pid; + int res; + + /* + * Make sure we can open the files we're going to redirect to. If this + * fails, we want to complain before disconnecting. Mention the full path + * of the logfile in the error message, even though we address it by + * relative path. + */ + dvnull = open(DEVNULL, O_RDONLY, 0); + if (dvnull < 0) + { + write_stderr("%s: could not open file \"%s\": %s\n", + progname, DEVNULL, strerror(errno)); + ExitPostmaster(1); + } + pmlog = open(pmlogname, O_CREAT | O_WRONLY | O_APPEND, 0600); + if (pmlog < 0) + { + write_stderr("%s: could not open log file \"%s/%s\": %s\n", + progname, DataDir, pmlogname, strerror(errno)); + ExitPostmaster(1); + } + /* + * Okay to fork. + */ pid = fork_process(); if (pid == (pid_t) -1) { @@ -1231,8 +1262,8 @@ pmdaemonize(void) MyStartTime = time(NULL); /* - * GH: If there's no setsid(), we hopefully don't need silent mode. Until - * there's a better solution. + * Some systems use setsid() to dissociate from the TTY's process group, + * while on others it depends on stdin/stdout/stderr. Do both if possible. */ #ifdef HAVE_SETSID if (setsid() < 0) @@ -1242,14 +1273,26 @@ pmdaemonize(void) ExitPostmaster(1); } #endif - i = open(DEVNULL, O_RDWR, 0); - dup2(i, 0); - dup2(i, 1); - dup2(i, 2); - close(i); + + /* + * Reassociate stdin/stdout/stderr. fork_process() cleared any pending + * output, so this should be safe. The only plausible error is EINTR, + * which just means we should retry. + */ + do { + res = dup2(dvnull, 0); + } while (res < 0 && errno == EINTR); + close(dvnull); + do { + res = dup2(pmlog, 1); + } while (res < 0 && errno == EINTR); + do { + res = dup2(pmlog, 2); + } while (res < 0 && errno == EINTR); + close(pmlog); #else /* WIN32 */ /* not supported */ - elog(FATAL, "SilentMode not supported under WIN32"); + elog(FATAL, "silent_mode is not supported under Windows"); #endif /* WIN32 */ } @@ -3241,8 +3284,8 @@ BackendInitialize(Port *port) if (!load_hba()) { /* - * It makes no sense continue if we fail to load the HBA file, since - * there is no way to connect to the database in this case. + * It makes no sense to continue if we fail to load the HBA file, + * since there is no way to connect to the database in this case. */ ereport(FATAL, (errmsg("could not load pg_hba.conf"))); diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 264b45451a966e2c959170f8303030813c3dde90..0fe3b4b98cf1e34d9f60c9cc44896a66ff687639 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut <peter_e@gmx.net>. * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.510 2009/08/04 16:08:36 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.511 2009/08/24 20:08:32 tgl Exp $ * *-------------------------------------------------------------------- */ @@ -734,7 +734,7 @@ static struct config_bool ConfigureNamesBool[] = true, NULL, NULL }, { - {"silent_mode", PGC_POSTMASTER, LOGGING_WHEN, + {"silent_mode", PGC_POSTMASTER, LOGGING_WHERE, gettext_noop("Runs the server silently."), gettext_noop("If this parameter is set, the server will automatically run in the " "background and any controlling terminals are dissociated.") diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 41488e264f06a11a7a757fb13c71a218c3c1a3e2..c6c02fcd812ab8d4186cbc1b7dbd0b383ef3e771 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -265,6 +265,11 @@ #syslog_facility = 'LOCAL0' #syslog_ident = 'postgres' +#silent_mode = off # Run server silently. + # DO NOT USE without syslog or + # logging_collector + # (change requires restart) + # - When to Log - @@ -314,9 +319,6 @@ # statements running at least this number # of milliseconds -#silent_mode = off # DO NOT USE without syslog or - # logging_collector - # (change requires restart) # - What to Log -