Commit dad8e410 authored by Tom Lane's avatar Tom Lane

Fix handling of SIGCHLD, per recent pghackers discussion: on some

platforms system(2) gets confused unless the signal handler is set to
SIG_DFL, not SIG_IGN.  pgstats.c now uses pqsignal() as it should,
not signal().  Also, arrange for the stats collector process to show
a reasonable ID in 'ps', rather than looking like a postmaster.
parent 2b769c82
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.112 2001/07/16 05:06:57 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.113 2001/08/04 00:14:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -310,13 +310,15 @@ BootstrapMain(int argc, char *argv[]) ...@@ -310,13 +310,15 @@ BootstrapMain(int argc, char *argv[])
pqsignal(SIGINT, SIG_IGN); /* ignore query-cancel */ pqsignal(SIGINT, SIG_IGN); /* ignore query-cancel */
pqsignal(SIGTERM, die); pqsignal(SIGTERM, die);
pqsignal(SIGQUIT, quickdie); pqsignal(SIGQUIT, quickdie);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, SIG_IGN); pqsignal(SIGUSR1, SIG_IGN);
pqsignal(SIGUSR2, SIG_IGN); pqsignal(SIGUSR2, SIG_IGN);
/* /*
* Reset some signals that are accepted by postmaster but not here * Reset some signals that are accepted by postmaster but not here
*/ */
pqsignal(SIGCHLD, SIG_IGN); pqsignal(SIGCHLD, SIG_DFL);
pqsignal(SIGTTIN, SIG_DFL); pqsignal(SIGTTIN, SIG_DFL);
pqsignal(SIGTTOU, SIG_DFL); pqsignal(SIGTTOU, SIG_DFL);
pqsignal(SIGCONT, SIG_DFL); pqsignal(SIGCONT, SIG_DFL);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.76 2001/07/02 20:50:46 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.77 2001/08/04 00:14:43 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -58,7 +58,6 @@ createdb(const char *dbname, const char *dbpath, ...@@ -58,7 +58,6 @@ createdb(const char *dbname, const char *dbpath,
char *target_dir; char *target_dir;
char src_loc[MAXPGPATH]; char src_loc[MAXPGPATH];
char buf[2 * MAXPGPATH + 100]; char buf[2 * MAXPGPATH + 100];
int ret;
bool use_super, bool use_super,
use_createdb; use_createdb;
Oid src_dboid; Oid src_dboid;
...@@ -195,9 +194,7 @@ createdb(const char *dbname, const char *dbpath, ...@@ -195,9 +194,7 @@ createdb(const char *dbname, const char *dbpath,
/* Copy the template database to the new location */ /* Copy the template database to the new location */
snprintf(buf, sizeof(buf), "cp -r '%s' '%s'", src_loc, target_dir); snprintf(buf, sizeof(buf), "cp -r '%s' '%s'", src_loc, target_dir);
ret = system(buf); if (system(buf) != 0)
/* Some versions of SunOS seem to return ECHILD after a system() call */
if (ret != 0 && errno != ECHILD)
{ {
if (remove_dbdirs(nominal_loc, alt_loc)) if (remove_dbdirs(nominal_loc, alt_loc))
elog(ERROR, "CREATE DATABASE: could not initialize database directory"); elog(ERROR, "CREATE DATABASE: could not initialize database directory");
...@@ -557,7 +554,7 @@ remove_dbdirs(const char *nominal_loc, const char *alt_loc) ...@@ -557,7 +554,7 @@ remove_dbdirs(const char *nominal_loc, const char *alt_loc)
snprintf(buf, sizeof(buf), "rm -rf '%s'", target_dir); snprintf(buf, sizeof(buf), "rm -rf '%s'", target_dir);
if (system(buf) != 0 && errno != ECHILD) if (system(buf) != 0)
{ {
elog(NOTICE, "database directory '%s' could not be removed", elog(NOTICE, "database directory '%s' could not be removed",
target_dir); target_dir);
......
...@@ -16,41 +16,41 @@ ...@@ -16,41 +16,41 @@
* *
* Copyright (c) 2001, PostgreSQL Global Development Group * Copyright (c) 2001, PostgreSQL Global Development Group
* *
* $Id: pgstat.c,v 1.4 2001/07/05 15:19:40 wieck Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.5 2001/08/04 00:14:43 tgl Exp $
* ---------- * ----------
*/ */
#include "postgres.h" #include "postgres.h"
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include "access/xact.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_database.h"
#include "libpq/pqsignal.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "utils/memutils.h" #include "utils/memutils.h"
#include "storage/backendid.h" #include "storage/backendid.h"
#include "utils/rel.h" #include "utils/rel.h"
#include "utils/hsearch.h" #include "utils/hsearch.h"
#include "utils/ps_status.h"
#include "utils/syscache.h" #include "utils/syscache.h"
#include "access/xact.h"
#include "access/heapam.h"
#include "catalog/catname.h"
#include "catalog/pg_shadow.h"
#include "catalog/pg_database.h"
#include "pgstat.h" #include "pgstat.h"
/* ---------- /* ----------
* Global data * GUC parameters
* ---------- * ----------
*/ */
bool pgstat_collect_startcollector = true; bool pgstat_collect_startcollector = true;
...@@ -95,8 +95,8 @@ static char pgStat_fname[MAXPGPATH]; ...@@ -95,8 +95,8 @@ static char pgStat_fname[MAXPGPATH];
* Local function forward declarations * Local function forward declarations
* ---------- * ----------
*/ */
static void pgstat_main(void); static void pgstat_main(int real_argc, char *real_argv[]);
static void pgstat_recvbuffer(void); static void pgstat_recvbuffer(int real_argc, char *real_argv[]);
static int pgstat_add_backend(PgStat_MsgHdr *msg); static int pgstat_add_backend(PgStat_MsgHdr *msg);
static void pgstat_sub_backend(int procpid); static void pgstat_sub_backend(int procpid);
...@@ -227,11 +227,14 @@ pgstat_init(void) ...@@ -227,11 +227,14 @@ pgstat_init(void)
* pgstat_start() - * pgstat_start() -
* *
* Called from postmaster at startup or after an existing collector * Called from postmaster at startup or after an existing collector
* died. Fire up a fresh statistics collector. * died. Fire up a fresh statistics collector.
*
* The process' original argc and argv are passed, because they are
* needed by init_ps_display() on some platforms.
* ---------- * ----------
*/ */
int int
pgstat_start(void) pgstat_start(int real_argc, char *real_argv[])
{ {
/* /*
* Do nothing if no collector needed * Do nothing if no collector needed
...@@ -267,7 +270,8 @@ pgstat_start(void) ...@@ -267,7 +270,8 @@ pgstat_start(void)
return 0; return 0;
} }
pgstat_main(); pgstat_main(real_argc, real_argv);
exit(0); exit(0);
} }
...@@ -989,15 +993,6 @@ pgstat_fetch_stat_numbackends(void) ...@@ -989,15 +993,6 @@ pgstat_fetch_stat_numbackends(void)
/* ------------------------------------------------------------ /* ------------------------------------------------------------
* Local support functions follow * Local support functions follow
* ------------------------------------------------------------ * ------------------------------------------------------------
...@@ -1053,7 +1048,7 @@ pgstat_send(void *msg, int len) ...@@ -1053,7 +1048,7 @@ pgstat_send(void *msg, int len)
* ---------- * ----------
*/ */
static void static void
pgstat_main(void) pgstat_main(int real_argc, char *real_argv[])
{ {
PgStat_Msg msg; PgStat_Msg msg;
fd_set rfds; fd_set rfds;
...@@ -1076,27 +1071,22 @@ pgstat_main(void) ...@@ -1076,27 +1071,22 @@ pgstat_main(void)
/* /*
* Ignore all signals usually bound to some action in the postmaster * Ignore all signals usually bound to some action in the postmaster
*/ */
signal(SIGHUP, SIG_IGN); pqsignal(SIGHUP, SIG_IGN);
signal(SIGINT, SIG_IGN); pqsignal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN); pqsignal(SIGTERM, SIG_IGN);
signal(SIGTERM, SIG_IGN); pqsignal(SIGQUIT, SIG_IGN);
signal(SIGALRM, SIG_IGN); pqsignal(SIGALRM, SIG_IGN);
signal(SIGPIPE, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN);
signal(SIGUSR1, SIG_IGN); pqsignal(SIGUSR1, SIG_IGN);
signal(SIGUSR2, SIG_IGN); pqsignal(SIGUSR2, SIG_IGN);
signal(SIGCHLD, SIG_IGN); pqsignal(SIGCHLD, SIG_DFL);
signal(SIGTTIN, SIG_IGN); pqsignal(SIGTTIN, SIG_DFL);
signal(SIGTTOU, SIG_IGN); pqsignal(SIGTTOU, SIG_DFL);
signal(SIGWINCH, SIG_IGN); pqsignal(SIGCONT, SIG_DFL);
pqsignal(SIGWINCH, SIG_DFL);
/*
* Write the initial status file right at startup /*
*/ * Start a buffering subprocess to read from the socket, so
gettimeofday(&next_statwrite, NULL);
need_statwrite = TRUE;
/*
* Now we start the buffer process to read from the socket, so
* we have a little more time to process incoming messages. * we have a little more time to process incoming messages.
*/ */
if (pipe(pgStatPipe) < 0) if (pipe(pgStatPipe) < 0)
...@@ -1107,19 +1097,38 @@ pgstat_main(void) ...@@ -1107,19 +1097,38 @@ pgstat_main(void)
switch(fork()) switch(fork())
{ {
case -1: perror("PGSTAT: fork(2)"); case -1:
exit(1); perror("PGSTAT: fork(2)");
exit(1);
case 0: close(pgStatPipe[0]); case 0:
signal(SIGPIPE, SIG_DFL); close(pgStatPipe[0]);
pgstat_recvbuffer(); /* child process should die if can't pipe to parent collector */
exit(2); pqsignal(SIGPIPE, SIG_DFL);
pgstat_recvbuffer(real_argc, real_argv);
exit(2);
default: close(pgStatPipe[1]); default:
close(pgStatSock); close(pgStatPipe[1]);
break; close(pgStatSock);
break;
} }
/*
* Identify myself via ps
*
* WARNING: On some platforms the environment will be moved around to
* make room for the ps display string.
*/
init_ps_display(real_argc, real_argv, "stats collector process", "", "");
set_ps_display("");
/*
* Arrange to write the initial status file right away
*/
gettimeofday(&next_statwrite, NULL);
need_statwrite = TRUE;
/* /*
* Read in an existing statistics stats file or initialize the * Read in an existing statistics stats file or initialize the
* stats to zero. * stats to zero.
...@@ -1358,7 +1367,7 @@ pgstat_main(void) ...@@ -1358,7 +1367,7 @@ pgstat_main(void)
* ---------- * ----------
*/ */
static void static void
pgstat_recvbuffer(void) pgstat_recvbuffer(int real_argc, char *real_argv[])
{ {
fd_set rfds; fd_set rfds;
fd_set wfds; fd_set wfds;
...@@ -1373,6 +1382,15 @@ pgstat_recvbuffer(void) ...@@ -1373,6 +1382,15 @@ pgstat_recvbuffer(void)
int fromlen; int fromlen;
int overflow = 0; int overflow = 0;
/*
* Identify myself via ps
*
* WARNING: On some platforms the environment will be moved around to
* make room for the ps display string.
*/
init_ps_display(real_argc, real_argv, "stats buffer process", "", "");
set_ps_display("");
/* /*
* Allocate the message buffer * Allocate the message buffer
*/ */
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.233 2001/07/31 22:55:45 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.234 2001/08/04 00:14:43 tgl Exp $
* *
* NOTES * NOTES
* *
...@@ -696,7 +696,7 @@ PostmasterMain(int argc, char *argv[]) ...@@ -696,7 +696,7 @@ PostmasterMain(int argc, char *argv[])
*/ */
if (pgstat_init() < 0) if (pgstat_init() < 0)
ExitPostmaster(1); ExitPostmaster(1);
if (pgstat_start() < 0) if (pgstat_start(real_argc, real_argv) < 0)
ExitPostmaster(1); ExitPostmaster(1);
/* /*
...@@ -1488,7 +1488,7 @@ reaper(SIGNAL_ARGS) ...@@ -1488,7 +1488,7 @@ reaper(SIGNAL_ARGS)
{ {
fprintf(stderr, "%s: Performance collector exited with status %d\n", fprintf(stderr, "%s: Performance collector exited with status %d\n",
progname, exitstatus); progname, exitstatus);
pgstat_start(); pgstat_start(real_argc, real_argv);
continue; continue;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.229 2001/07/31 22:55:45 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.230 2001/08/04 00:14:43 tgl Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -1102,7 +1102,9 @@ usage(char *progname) ...@@ -1102,7 +1102,9 @@ usage(char *progname)
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
int int
PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const char *username) PostgresMain(int argc, char *argv[],
int real_argc, char *real_argv[],
const char *username)
{ {
int flag; int flag;
...@@ -1535,15 +1537,15 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1535,15 +1537,15 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
*/ */
pqsignal(SIGPIPE, SIG_IGN); pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, SIG_IGN); /* this signal available for use */ pqsignal(SIGUSR1, SIG_IGN); /* this signal available for use */
pqsignal(SIGUSR2, Async_NotifyHandler); /* flush also sinval cache */ pqsignal(SIGUSR2, Async_NotifyHandler); /* flush also sinval cache */
pqsignal(SIGFPE, FloatExceptionHandler); pqsignal(SIGFPE, FloatExceptionHandler);
pqsignal(SIGCHLD, SIG_IGN); /* ignored (may get this in system()
* calls) */
/* /*
* Reset some signals that are accepted by postmaster but not by * Reset some signals that are accepted by postmaster but not by
* backend * backend
*/ */
pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some platforms */
pqsignal(SIGTTIN, SIG_DFL); pqsignal(SIGTTIN, SIG_DFL);
pqsignal(SIGTTOU, SIG_DFL); pqsignal(SIGTTOU, SIG_DFL);
pqsignal(SIGCONT, SIG_DFL); pqsignal(SIGCONT, SIG_DFL);
...@@ -1711,7 +1713,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1711,7 +1713,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.229 $ $Date: 2001/07/31 22:55:45 $\n"); puts("$Revision: 1.230 $ $Date: 2001/08/04 00:14:43 $\n");
} }
/* /*
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* Copyright (c) 2001, PostgreSQL Global Development Group * Copyright (c) 2001, PostgreSQL Global Development Group
* *
* $Id: pgstat.h,v 1.4 2001/07/05 15:19:40 wieck Exp $ * $Id: pgstat.h,v 1.5 2001/08/04 00:14:43 tgl Exp $
* ---------- * ----------
*/ */
#ifndef PGSTAT_H #ifndef PGSTAT_H
...@@ -336,7 +336,7 @@ extern bool pgstat_collect_blocklevel; ...@@ -336,7 +336,7 @@ extern bool pgstat_collect_blocklevel;
* ---------- * ----------
*/ */
extern int pgstat_init(void); extern int pgstat_init(void);
extern int pgstat_start(void); extern int pgstat_start(int real_argc, char *real_argv[]);
extern int pgstat_ispgstat(int pid); extern int pgstat_ispgstat(int pid);
extern void pgstat_beterm(int pid); extern void pgstat_beterm(int pid);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment