On Thu, 20 Sep 2012 at 10:31, Heikki Linnakangas wrote:
I believe Tom is referring to the removal of silent_mode in 9.2, see http://archives.postgresql.org/pgsql-general/2011-06/msg00796.php and http://archives.postgresql.org/pgsql-hackers/2011-06/msg02156.php. "We removed logic associated with daemonization" meant that the logic was removed from postmaster, because the preferred way to do it is by calling "pg_ctl start". pg_ctl redirects to /dev/null as you'd expect.
Well, I was involved in that discussion and as a consequence stopped using silent_mode in the SUSE RPMs. That's what triggered the problem and I just verified that it still exists on 9.2.
After starting PostgreSQL with pg_init, stdout and stderr of all processes are pipes to the logger (as intended), but the logger itself still has FDs 1 and 2 open as inherited from pg_init. I think requiring the caller of pg_init to redirect them is not practical, because then pg_init itself can't give feedback to the user. So it has to be done either in pg_init or in the logger when those channels aren't needed anymore. I'd prefer doing it in the logger, because the code for it is already there and so that it also works when starting PostgreSQL without using pg_init.
I've attached the patch I sent to Peter which applies to 9.1 and 9.2.It also fixes a problem with the reopening of stdout and stderr from /dev/null where the temporary FD must not be closed if it is either 1 or 2, which is quite likely to happen as we've just closed these two and open() typically gets the lowest unused FD number.
BTW, I think the other dup2() for stderr in syslogger.c should get such a check as well, even if the clash is less likely to happen there.
cu Reinhard
--- src/backend/postmaster/syslogger.c +++ src/backend/postmaster/syslogger.c @@ -184,31 +184,22 @@ SysLoggerMain(int argc, char *argv[]) init_ps_display("logger process", "", "", ""); + int fd = open(DEVNULL, O_WRONLY, 0); + /* - * If we restarted, our stderr is already redirected into our own input - * pipe. This is of course pretty useless, not to mention that it - * interferes with detecting pipe EOF. Point stderr to /dev/null. This - * assumes that all interesting messages generated in the syslogger will - * come through elog.c and will be sent to write_syslogger_file. + * The closes might look redundant, but they are not: we want to be + * darn sure the pipe gets closed even if the open failed. We can + * survive running with stderr pointing nowhere, but we can't afford + * to have extra pipe input descriptors hanging around. */ - if (redirection_done) + close(fileno(stdout)); + close(fileno(stderr)); + if (fd != -1) { - int fd = open(DEVNULL, O_WRONLY, 0); - - /* - * The closes might look redundant, but they are not: we want to be - * darn sure the pipe gets closed even if the open failed. We can - * survive running with stderr pointing nowhere, but we can't afford - * to have extra pipe input descriptors hanging around. - */ - close(fileno(stdout)); - close(fileno(stderr)); - if (fd != -1) - { - dup2(fd, fileno(stdout)); - dup2(fd, fileno(stderr)); + dup2(fd, fileno(stdout)); + dup2(fd, fileno(stderr)); + if (fd != fileno(stdout) && fd != fileno(stderr)) close(fd); - } } /*
-- Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-bugs