diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-11-21 20:59:53 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-11-21 20:59:53 +0000 |
commit | 3ad0728c817bf8abd2c76bd11d856967509b307c (patch) | |
tree | ffaf56c059f678d2b41390027b8b9b973660cb7c /src/backend/postmaster/pgarch.c | |
parent | de597154a8acae01be28ba32b5b6e0ec4915ef3f (diff) | |
download | postgresql-3ad0728c817bf8abd2c76bd11d856967509b307c.tar.gz postgresql-3ad0728c817bf8abd2c76bd11d856967509b307c.zip |
On systems that have setsid(2) (which should be just about everything except
Windows), arrange for each postmaster child process to be its own process
group leader, and deliver signals SIGINT, SIGTERM, SIGQUIT to the whole
process group not only the direct child process. This provides saner behavior
for archive and recovery scripts; in particular, it's possible to shut down a
warm-standby recovery server using "pg_ctl stop -m immediate", since delivery
of SIGQUIT to the startup subprocess will result in killing the waiting
recovery_command. Also, this makes Query Cancel and statement_timeout apply
to scripts being run from backends via system(). (There is no support in the
core backend for that, but it's widely done using untrusted PLs.) Per gripe
from Stephen Harris and subsequent discussion.
Diffstat (limited to 'src/backend/postmaster/pgarch.c')
-rw-r--r-- | src/backend/postmaster/pgarch.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index a40bf47b3aa..ba8a396c2e5 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -19,7 +19,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.26 2006/11/10 22:32:20 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/postmaster/pgarch.c,v 1.27 2006/11/21 20:59:52 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -29,6 +29,7 @@ #include <signal.h> #include <time.h> #include <sys/time.h> +#include <sys/wait.h> #include <unistd.h> #include "access/xlog_internal.h" @@ -223,6 +224,15 @@ PgArchiverMain(int argc, char *argv[]) MyProcPid = getpid(); /* reset MyProcPid */ /* + * If possible, make this process a group leader, so that the postmaster + * can signal any child processes too. + */ +#ifdef HAVE_SETSID + if (setsid() < 0) + elog(FATAL, "setsid() failed: %m"); +#endif + + /* * Ignore all signals usually bound to some action in the postmaster, * except for SIGHUP, SIGUSR1 and SIGQUIT. */ @@ -456,9 +466,22 @@ pgarch_archiveXlog(char *xlog) rc = system(xlogarchcmd); if (rc != 0) { - ereport(LOG, + /* + * If either the shell itself, or a called command, died on a signal, + * abort the archiver. We do this because system() ignores SIGINT and + * SIGQUIT while waiting; so a signal is very likely something that + * should have interrupted us too. If we overreact it's no big deal, + * the postmaster will just start the archiver again. + * + * Per the Single Unix Spec, shells report exit status > 128 when + * a called command died on a signal. + */ + bool signaled = WIFSIGNALED(rc) || WEXITSTATUS(rc) > 128; + + ereport(signaled ? FATAL : LOG, (errmsg("archive command \"%s\" failed: return code %d", xlogarchcmd, rc))); + return false; } ereport(LOG, |