Code review for EXEC_BACKEND changes. Reduce the number of #ifdefs by

about a third, make it work on non-Windows platforms again.  (But perhaps
I broke the WIN32 code, since I have no way to test that.)  Fold all the
paths that fork postmaster child processes to go through the single
routine SubPostmasterMain, which takes care of resurrecting the state that
would normally be inherited from the postmaster (including GUC variables).
Clean up some places where there's no particularly good reason for the
EXEC and non-EXEC cases to work differently.  Take care of one or two
FIXMEs that remained in the code.
This commit is contained in:
Tom Lane 2004-05-28 05:13:32 +00:00
parent 37da0ba0e0
commit 1a321f26d8
19 changed files with 788 additions and 807 deletions

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.13 2004/02/23 23:03:10 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/slru.c,v 1.14 2004/05/28 05:12:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -164,10 +164,9 @@ static bool SlruScanDirectory(SlruCtl ctl, int cutoffPage, bool doDeletions);
int
SimpleLruShmemSize(void)
{
return MAXALIGN(sizeof(SlruSharedData)) + BLCKSZ * NUM_CLOG_BUFFERS
#ifdef EXEC_BACKEND
return MAXALIGN(sizeof(SlruSharedData))
+ BLCKSZ * NUM_CLOG_BUFFERS
+ MAXALIGN(sizeof(SlruLockData))
#endif
;
}
@ -181,21 +180,8 @@ SimpleLruInit(SlruCtl ctl, const char *name, const char *subdir)
ptr = ShmemInitStruct(name, SimpleLruShmemSize(), &found);
shared = (SlruShared) ptr;
#ifdef EXEC_BACKEND
/*
* Locks are in shared memory
*/
locks = (SlruLock) (ptr + MAXALIGN(sizeof(SlruSharedData)) +
BLCKSZ * NUM_CLOG_BUFFERS);
#else
/*
* Locks are in private memory
*/
Assert(!IsUnderPostmaster);
locks = malloc(sizeof(SlruLockData));
Assert(locks);
#endif
if (!IsUnderPostmaster)
{
@ -225,6 +211,7 @@ SimpleLruInit(SlruCtl ctl, const char *name, const char *subdir)
else
Assert(found);
/* Initialize the unshared control struct */
ctl->locks = locks;
ctl->shared = shared;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.143 2004/05/27 17:12:42 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.144 2004/05/28 05:12:42 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -397,7 +397,7 @@ static char ControlFilePath[MAXPGPATH];
* Private, possibly out-of-date copy of shared LogwrtResult.
* See discussion above.
*/
NON_EXEC_STATIC XLogwrtResult LogwrtResult = {{0, 0}, {0, 0}};
static XLogwrtResult LogwrtResult = {{0, 0}, {0, 0}};
/*
* openLogFile is -1 or a kernel FD for an open log file segment.

View File

@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.180 2004/05/27 17:12:49 tgl Exp $
* $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.181 2004/05/28 05:12:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -43,17 +43,12 @@
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/ps_status.h"
#include "utils/relcache.h"
#define ALLOC(t, c) ((t *) calloc((unsigned)(c), sizeof(t)))
#ifdef EXEC_BACKEND
typedef struct Port Port;
extern void SSDataBaseInit(int);
extern void read_backend_variables(unsigned long, Port*);
#endif
extern int Int_yyparse(void);
static hashnode *AddStr(char *str, int strlength, int mderef);
static Form_pg_attribute AllocateAttribute(void);
@ -233,34 +228,29 @@ usage(void)
}
int
BootstrapMain(int argc, char *argv[])
/* ----------------------------------------------------------------
* The main loop for handling the backend in bootstrap mode
* the bootstrap mode is used to initialize the template database
* the bootstrap backend doesn't speak SQL, but instead expects
/*
* The main loop for running the backend in bootstrap mode
*
* The bootstrap mode is used to initialize the template database.
* The bootstrap backend doesn't speak SQL, but instead expects
* commands in a special bootstrap language.
*
* The arguments passed in to BootstrapMain are the run-time arguments
* without the argument '-boot', the caller is required to have
* removed -boot from the run-time args
* ----------------------------------------------------------------
* For historical reasons, BootstrapMain is also used as the control
* routine for non-backend subprocesses launched by the postmaster,
* such as startup and shutdown.
*/
int
BootstrapMain(int argc, char *argv[])
{
int i;
char *dbname;
int flag;
int xlogop = BS_XLOG_NOP;
char *potential_DataDir = NULL;
#ifdef EXEC_BACKEND
unsigned long backendID = 0;
#endif
/*
* initialize globals
*/
MyProcPid = getpid();
/*
@ -268,7 +258,7 @@ BootstrapMain(int argc, char *argv[])
*
* If we are running under the postmaster, this is done already.
*/
if (!IsUnderPostmaster || ExecBackend)
if (!IsUnderPostmaster)
MemoryContextInit();
/*
@ -284,6 +274,13 @@ BootstrapMain(int argc, char *argv[])
* variable */
}
/* Ignore the initial -boot argument, if present */
if (argc > 1 && strcmp(argv[1], "-boot") == 0)
{
argv++;
argc--;
}
while ((flag = getopt(argc, argv, "B:c:d:D:Fo:p:x:-:")) != -1)
{
switch (flag)
@ -315,14 +312,6 @@ BootstrapMain(int argc, char *argv[])
xlogop = atoi(optarg);
break;
case 'p':
#ifdef EXEC_BACKEND
{
char buf[MAXPGPATH];
IsUnderPostmaster = true;
sscanf(optarg,"%lu,%s",&backendID,buf);
dbname = strdup(buf);
}
#endif
dbname = strdup(optarg);
break;
case 'B':
@ -369,7 +358,7 @@ BootstrapMain(int argc, char *argv[])
if (!dbname || argc != optind)
usage();
if (!IsUnderPostmaster || ExecBackend)
if (!IsUnderPostmaster)
{
if (!potential_DataDir)
{
@ -388,21 +377,43 @@ BootstrapMain(int argc, char *argv[])
Assert(DataDir);
ValidatePgVersion(DataDir);
/* Acquire configuration parameters */
/*
* Identify myself via ps
*/
if (IsUnderPostmaster)
{
#ifdef EXEC_BACKEND
read_backend_variables(backendID,NULL);
read_nondefault_variables();
const char *statmsg;
SSDataBaseInit(xlogop);
#endif
switch (xlogop)
{
case BS_XLOG_STARTUP:
statmsg = "startup subprocess";
break;
case BS_XLOG_CHECKPOINT:
statmsg = "checkpoint subprocess";
break;
case BS_XLOG_BGWRITER:
statmsg = "bgwriter subprocess";
break;
case BS_XLOG_SHUTDOWN:
statmsg = "shutdown subprocess";
break;
default:
statmsg = "??? subprocess";
break;
}
init_ps_display(statmsg, "", "");
set_ps_display("");
}
else
/* Acquire configuration parameters, unless inherited from postmaster */
if (!IsUnderPostmaster)
{
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
}
if (IsUnderPostmaster)
{
@ -450,10 +461,6 @@ BootstrapMain(int argc, char *argv[])
SetProcessingMode(BootstrapProcessing);
IgnoreSystemIndexes(true);
#ifdef EXEC_BACKEND
if (IsUnderPostmaster)
CreateSharedMemoryAndSemaphores(false, MaxBackends, 0);
#endif
XLOGPathInit();
BaseInit();

View File

@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.83 2004/05/27 15:07:40 momjian Exp $
* $PostgreSQL: pgsql/src/backend/main/main.c,v 1.84 2004/05/28 05:12:50 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -242,9 +242,9 @@ main(int argc, char *argv[])
/*
* Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
* SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain
* depending on the program name (and possibly first argument) we were
* called with. The lack of consistency here is historical.
* SubPostmasterMain, or BootstrapMain depending on the program name
* (and possibly first argument) we were called with. The lack of
* consistency here is historical.
*/
len = strlen(argv[0]);
@ -259,43 +259,21 @@ main(int argc, char *argv[])
}
/*
* If the first argument is "-boot", then invoke bootstrap mode. Note
* we remove "-boot" from the arguments passed on to BootstrapMain.
* If the first argument begins with "-fork", then invoke
* SubPostmasterMain. This is used for forking postmaster child
* processes on systems where we can't simply fork.
*/
#ifdef EXEC_BACKEND
if (argc > 1 && strncmp(argv[1], "-fork", 5) == 0)
exit(SubPostmasterMain(argc, argv));
#endif
/*
* If the first argument is "-boot", then invoke bootstrap mode.
* (This path is taken only for a standalone bootstrap process.)
*/
if (argc > 1 && strcmp(argv[1], "-boot") == 0)
exit(BootstrapMain(argc - 1, argv + 1));
#ifdef EXEC_BACKEND
/*
* If the first argument is "-forkexec", then invoke
* SubPostmasterMain. Note we remove "-forkexec" from the arguments
* passed on to SubPostmasterMain.
*/
if (argc > 1 && strcmp(argv[1], "-forkexec") == 0)
{
SubPostmasterMain(argc - 2, argv + 2);
exit(0);
}
/*
* If the first argument is "-statBuf", then invoke pgstat_main.
*/
if (argc > 1 && strcmp(argv[1], "-statBuf") == 0)
{
pgstat_main(argc, argv);
exit(0);
}
/*
* If the first argument is "-statCol", then invoke pgstat_mainChild.
*/
if (argc > 1 && strcmp(argv[1], "-statCol") == 0)
{
pgstat_mainChild(argc, argv);
exit(0);
}
#endif
exit(BootstrapMain(argc, argv));
/*
* If the first argument is "--describe-config", then invoke runtime
@ -331,7 +309,7 @@ main(int argc, char *argv[])
exit(1);
}
}
#endif
#endif /* WIN32 */
exit(PostgresMain(argc, argv, pw_name_persist));
}

View File

@ -21,7 +21,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/port/ipc_test.c,v 1.12 2003/12/12 18:45:09 petere Exp $
* $PostgreSQL: pgsql/src/backend/port/ipc_test.c,v 1.13 2004/05/28 05:12:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -46,8 +46,6 @@ volatile bool ImmediateInterruptOK = false;
volatile uint32 InterruptHoldoffCount = 0;
volatile uint32 CritSectionCount = 0;
const bool ExecBackend = false;
bool IsUnderPostmaster = false;
int MaxBackends = 32;

View File

@ -9,11 +9,11 @@
* - Add some automatic call for pgstat vacuuming.
*
* - Add a pgstat config column to pg_database, so this
* entire thing can be enabled/disabled on a per db base.
* entire thing can be enabled/disabled on a per db basis.
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.71 2004/05/24 02:47:47 momjian Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.72 2004/05/28 05:12:58 tgl Exp $
* ----------
*/
#include "postgres.h"
@ -51,13 +51,6 @@
#include "utils/ps_status.h"
#include "utils/syscache.h"
#ifdef EXEC_BACKEND
#include "utils/guc.h"
#endif
#ifdef WIN32
extern pid_t win32_forkexec(const char* path, char *argv[]);
#endif
/* ----------
* GUC parameters
@ -107,8 +100,8 @@ static HTAB *pgStatBeDead = NULL;
static PgStat_StatBeEntry *pgStatBeTable = NULL;
static int pgStatNumBackends = 0;
static char pgStat_tmpfname[MAXPGPATH];
static char pgStat_fname[MAXPGPATH];
static char pgStat_tmpfname[MAXPGPATH];
/* ----------
@ -116,12 +109,20 @@ static char pgStat_fname[MAXPGPATH];
* ----------
*/
#ifdef EXEC_BACKEND
typedef enum STATS_PROCESS_TYPE
{
STAT_PROC_BUFFER,
STAT_PROC_COLLECTOR
} STATS_PROCESS_TYPE;
static pid_t pgstat_forkexec(STATS_PROCESS_TYPE procType);
static void pgstat_parseArgs(PGSTAT_FORK_ARGS);
static void pgstat_parseArgs(int argc, char *argv[]);
#endif
NON_EXEC_STATIC void pgstat_main(PGSTAT_FORK_ARGS);
NON_EXEC_STATIC void pgstat_mainChild(PGSTAT_FORK_ARGS);
static void pgstat_mainInit(void);
NON_EXEC_STATIC void PgstatBufferMain(int argc, char *argv[]);
NON_EXEC_STATIC void PgstatCollectorMain(int argc, char *argv[]);
static void pgstat_recvbuffer(void);
static void pgstat_die(SIGNAL_ARGS);
@ -150,18 +151,6 @@ static void pgstat_recv_resetcounter(PgStat_MsgResetcounter *msg, int len);
* ------------------------------------------------------------
*/
#ifdef EXEC_BACKEND
void
pgstat_init_forkexec_backend(void)
{
Assert(DataDir != NULL);
snprintf(pgStat_fname, MAXPGPATH,
PGSTAT_STAT_FILENAME, DataDir);
}
#endif
/* ----------
* pgstat_init() -
*
@ -195,12 +184,12 @@ pgstat_init(void)
pgstat_collect_startcollector = true;
/*
* Initialize the filenames for the status reports.
* Initialize the filename for the status reports. (In the EXEC_BACKEND
* case, this only sets the value in the postmaster. The collector
* subprocess will recompute the value for itself, and individual
* backends must do so also if they want to access the file.)
*/
snprintf(pgStat_tmpfname, MAXPGPATH,
PGSTAT_STAT_TMPFILE, DataDir, getpid());
snprintf(pgStat_fname, MAXPGPATH,
PGSTAT_STAT_FILENAME, DataDir);
snprintf(pgStat_fname, MAXPGPATH, PGSTAT_STAT_FILENAME, DataDir);
/*
* If we don't have to start a collector or should reset the collected
@ -441,112 +430,83 @@ startup_failed:
#ifdef EXEC_BACKEND
/* ----------
/*
* pgstat_forkexec() -
*
* Used to format up the arglist for, then fork and exec, statistics
* Format up the arglist for, then fork and exec, statistics
* (buffer and collector) processes
*
*/
static pid_t
pgstat_forkexec(STATS_PROCESS_TYPE procType)
{
pid_t pid;
char *av[15];
char *av[12];
int ac = 0, bufc = 0, i;
char pgstatBuf[12][MAXPGPATH];
char pgstatBuf[7][32];
av[ac++] = "postgres";
switch (procType)
{
case STAT_PROC_BUFFER:
av[ac++] = "-statBuf";
av[ac++] = "-forkbuf";
break;
case STAT_PROC_COLLECTOR:
av[ac++] = "-statCol";
av[ac++] = "-forkcol";
break;
default:
Assert(false);
}
/* Sockets + pipes */
bufc = 0;
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatSock);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPmPipe[0]);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPmPipe[1]);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatCollectorPmPipe[0]);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatCollectorPmPipe[1]);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPipe[0]);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",pgStatPipe[1]);
av[ac++] = NULL; /* filled in by postmaster_forkexec */
/* + misc */
snprintf(pgstatBuf[bufc++],MAXPGPATH,"%d",MaxBackends);
/* postgres_exec_path is not passed by write_backend_variables */
av[ac++] = postgres_exec_path;
/* + the pstat file names, and postgres pathname */
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pgStat_tmpfname);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",pgStat_fname);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",postgres_exec_path);
snprintf(pgstatBuf[bufc++],MAXPGPATH,"\"%s\"",DataDir);
/* Sockets + pipes (those not passed by write_backend_variables) */
snprintf(pgstatBuf[bufc++],32,"%d",pgStatPmPipe[0]);
snprintf(pgstatBuf[bufc++],32,"%d",pgStatPmPipe[1]);
snprintf(pgstatBuf[bufc++],32,"%d",pgStatCollectorPmPipe[0]);
snprintf(pgstatBuf[bufc++],32,"%d",pgStatCollectorPmPipe[1]);
snprintf(pgstatBuf[bufc++],32,"%d",pgStatPipe[0]);
snprintf(pgstatBuf[bufc++],32,"%d",pgStatPipe[1]);
/* Add to the arg list */
Assert(bufc <= lengthof(pgstatBuf));
for (i = 0; i < bufc; i++)
av[ac++] = pgstatBuf[i];
av[ac++] = NULL;
Assert(ac <= lengthof(av));
av[ac] = NULL;
Assert(ac < lengthof(av));
/* Fire off execv in child */
#ifdef WIN32
pid = win32_forkexec(postgres_exec_path, av);
#else
if ((pid = fork()) == 0 && (execv(postgres_exec_path, av) == -1))
/* FIXME: [fork/exec] suggestions for what to do here? Can't call elog... */
abort();
#endif
return pid; /* Parent returns pid */
return postmaster_forkexec(ac, av);
}
/* ----------
/*
* pgstat_parseArgs() -
*
* Used to unformat the arglist for exec'ed statistics
* Extract data from the arglist for exec'ed statistics
* (buffer and collector) processes
*
*/
static void
pgstat_parseArgs(PGSTAT_FORK_ARGS)
pgstat_parseArgs(int argc, char *argv[])
{
Assert(argc == 14);
Assert(argc == 10);
if (find_my_exec(argv[0], my_exec_path) < 0)
elog(FATAL,
gettext("%s: could not locate my own executable path"),
argv[0]);
get_pkglib_path(my_exec_path, pkglib_path);
argc = 2;
pgStatSock = atoi(argv[argc++]);
argc = 3;
StrNCpy(postgres_exec_path, argv[argc++], MAXPGPATH);
pgStatPmPipe[0] = atoi(argv[argc++]);
pgStatPmPipe[1] = atoi(argv[argc++]);
pgStatCollectorPmPipe[0] = atoi(argv[argc++]);
pgStatCollectorPmPipe[1] = atoi(argv[argc++]);
pgStatPipe[0] = atoi(argv[argc++]);
pgStatPipe[1] = atoi(argv[argc++]);
MaxBackends = atoi(argv[argc++]);
StrNCpy(pgStat_tmpfname,argv[argc++],MAXPGPATH);
StrNCpy(pgStat_fname, argv[argc++],MAXPGPATH);
StrNCpy(postgres_exec_path, argv[argc++],MAXPGPATH);
DataDir = strdup(argv[argc++]);
read_nondefault_variables();
}
#endif
#endif /* EXEC_BACKEND */
/* ----------
* pgstat_start() -
@ -638,7 +598,7 @@ pgstat_start(void)
/* Drop our connection to postmaster's shared memory, as well */
PGSharedMemoryDetach();
pgstat_main();
PgstatBufferMain(0, NULL);
break;
#endif
@ -1443,26 +1403,20 @@ pgstat_send(void *msg, int len)
}
/* ------------------------------------------------------------
* Local functions implementing the statistics collector itself follow
*------------------------------------------------------------
/* ----------
* PgstatBufferMain() -
*
* Start up the statistics buffer process. This is the body of the
* postmaster child process.
*
* The argc/argv parameters are valid only in EXEC_BACKEND case.
* ----------
*/
static void
pgstat_mainInit(void)
NON_EXEC_STATIC void
PgstatBufferMain(int argc, char *argv[])
{
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
#ifdef EXEC_BACKEND
/* In EXEC case we will not have inherited these settings */
IsPostmasterEnvironment = true;
whereToSendOutput = None;
/* Setup global context */
MemoryContextInit(); /* before any elog'ing can occur */
InitializeGUCOptions();
#endif
MyProcPid = getpid(); /* reset MyProcPid */
/* Lose the postmaster's on-exit routines */
@ -1485,20 +1439,8 @@ pgstat_mainInit(void)
pqsignal(SIGTTOU, SIG_DFL);
pqsignal(SIGCONT, SIG_DFL);
pqsignal(SIGWINCH, SIG_DFL);
}
/* unblock will happen in pgstat_recvbuffer */
/* ----------
* pgstat_main() -
*
* Start up the statistics collector itself. This is the body of the
* postmaster child process.
* ----------
*/
NON_EXEC_STATIC void
pgstat_main(PGSTAT_FORK_ARGS)
{
pgstat_mainInit(); /* Note: for *both* EXEC_BACKEND and regular cases */
#ifdef EXEC_BACKEND
pgstat_parseArgs(argc,argv);
#endif
@ -1547,7 +1489,7 @@ pgstat_main(PGSTAT_FORK_ARGS)
#ifndef EXEC_BACKEND
case 0:
/* child becomes collector process */
pgstat_mainChild();
PgstatCollectorMain(0, NULL);
break;
#endif
@ -1560,8 +1502,17 @@ pgstat_main(PGSTAT_FORK_ARGS)
}
/* ----------
* PgstatCollectorMain() -
*
* Start up the statistics collector itself. This is the body of the
* postmaster grandchild process.
*
* The argc/argv parameters are valid only in EXEC_BACKEND case.
* ----------
*/
NON_EXEC_STATIC void
pgstat_mainChild(PGSTAT_FORK_ARGS)
PgstatCollectorMain(int argc, char *argv[])
{
PgStat_Msg msg;
fd_set rfds;
@ -1574,29 +1525,52 @@ pgstat_mainChild(PGSTAT_FORK_ARGS)
bool need_statwrite;
HASHCTL hash_ctl;
#ifdef EXEC_BACKEND
pgstat_mainInit(); /* Note: only in EXEC_BACKEND case */
pgstat_parseArgs(argc,argv);
#else
MyProcPid = getpid(); /* reset MyProcPid */
/*
* Reset signal handling. With the exception of restoring default
* SIGCHLD handling, this is a no-op in the non-EXEC_BACKEND case
* because we'll have inherited these settings from the buffer process;
* but it's not a no-op for EXEC_BACKEND.
*/
pqsignal(SIGHUP, SIG_IGN);
pqsignal(SIGINT, SIG_IGN);
pqsignal(SIGTERM, SIG_IGN);
pqsignal(SIGQUIT, SIG_IGN);
pqsignal(SIGALRM, SIG_IGN);
pqsignal(SIGPIPE, SIG_IGN);
pqsignal(SIGUSR1, SIG_IGN);
pqsignal(SIGUSR2, SIG_IGN);
pqsignal(SIGCHLD, SIG_DFL);
pqsignal(SIGTTIN, SIG_DFL);
pqsignal(SIGTTOU, SIG_DFL);
pqsignal(SIGCONT, SIG_DFL);
pqsignal(SIGWINCH, SIG_DFL);
PG_SETMASK(&UnBlockSig);
#ifdef EXEC_BACKEND
pgstat_parseArgs(argc,argv);
#endif
/* Close unwanted files */
closesocket(pgStatPipe[1]);
closesocket(pgStatSock);
pmPipe = pgStatCollectorPmPipe[0];
/*
* In the child we can have default SIGCHLD handling (in case we want
* to call system() here...)
*/
pqsignal(SIGCHLD, SIG_DFL);
/*
* Identify myself via ps
*/
init_ps_display("stats collector process", "", "");
set_ps_display("");
/*
* Initialize filenames needed for status reports.
*/
snprintf(pgStat_fname, MAXPGPATH, PGSTAT_STAT_FILENAME, DataDir);
/* tmpfname need only be set correctly in this process */
snprintf(pgStat_tmpfname, MAXPGPATH, PGSTAT_STAT_TMPFILE,
DataDir, getpid());
/*
* Arrange to write the initial status file right away
*/
@ -2549,6 +2523,18 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
if (betab != NULL)
*betab = NULL;
/*
* In EXEC_BACKEND case, we won't have inherited pgStat_fname from
* postmaster, so compute it first time through.
*/
#ifdef EXEC_BACKEND
if (pgStat_fname[0] == '\0')
{
Assert(DataDir != NULL);
snprintf(pgStat_fname, MAXPGPATH, PGSTAT_STAT_FILENAME, DataDir);
}
#endif
/*
* Try to open the status file. If it doesn't exist, the backends
* simply return zero for anything and the collector simply starts

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.65 2004/04/22 07:21:55 neilc Exp $
* $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.66 2004/05/28 05:13:01 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -93,15 +93,6 @@ InitBufferPool(void)
foundDescs;
int i;
/*
* It's probably not really necessary to grab the lock --- if there's
* anyone else attached to the shmem at this point, we've got
* problems.
*/
#ifndef EXEC_BACKEND
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
#endif
BufferDescriptors = (BufferDesc *)
ShmemInitStruct("Buffer Descriptors",
NBuffers * sizeof(BufferDesc), &foundDescs);
@ -120,6 +111,13 @@ InitBufferPool(void)
BufferDesc *buf;
char *block;
/*
* It's probably not really necessary to grab the lock --- if there's
* anyone else attached to the shmem at this point, we've got
* problems.
*/
LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
buf = BufferDescriptors;
block = BufferBlocks;
@ -147,14 +145,12 @@ InitBufferPool(void)
/* Correct last entry */
BufferDescriptors[NBuffers - 1].bufNext = -1;
LWLockRelease(BufMgrLock);
}
/* Init other shared buffer-management stuff */
StrategyInitialize(!foundDescs);
#ifndef EXEC_BACKEND
LWLockRelease(BufMgrLock);
#endif
}
/*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.66 2004/04/19 23:27:17 tgl Exp $
* $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.67 2004/05/28 05:13:03 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -37,9 +37,13 @@
*
* This is called by the postmaster or by a standalone backend.
* It is also called by a backend forked from the postmaster under
* the EXEC_BACKEND case
*
* In the non EXEC_BACKEND case, backends already have shared memory ready-to-go.
* the EXEC_BACKEND case. (In the non EXEC_BACKEND case, backends
* start life already attached to shared memory.) The initialization
* functions are set up to simply "attach" to pre-existing shared memory
* structures in the latter case. We have to do that in order to
* initialize pointers in local memory that reference the shared structures.
* (In the non EXEC_BACKEND case, these pointer values are inherited via
* fork() from the postmaster.)
*
* If "makePrivate" is true then we only need private memory, not shared
* memory. This is true for a standalone backend, false for a postmaster.
@ -96,8 +100,12 @@ CreateSharedMemoryAndSemaphores(bool makePrivate,
* (this should only ever be reached by EXEC_BACKEND code,
* and only then with makePrivate == false)
*/
Assert(ExecBackend && !makePrivate);
#ifdef EXEC_BACKEND
Assert(!makePrivate);
seghdr = PGSharedMemoryCreate(-1, makePrivate, 0);
#else
Assert(false);
#endif
}

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.62 2003/12/01 21:59:25 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lmgr.c,v 1.63 2004/05/28 05:13:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -75,6 +75,13 @@ InitLockTable(int maxBackends)
{
LOCKMETHODID LongTermTableId;
/* there's no zero-th table */
NumLockMethods = 1;
/*
* Create the default lock method table
*/
/* number of lock modes is lengthof()-1 because of dummy zero */
LockTableId = LockMethodTableInit("LockTable",
LockConflicts,

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.131 2003/12/20 17:31:21 momjian Exp $
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.132 2004/05/28 05:13:05 tgl Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
@ -155,7 +155,9 @@ PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP)
static LockMethod LockMethods[MAX_LOCK_METHODS];
static HTAB* LockMethodLockHash[MAX_LOCK_METHODS];
static HTAB* LockMethodProcLockHash[MAX_LOCK_METHODS];
static int NumLockMethods;
/* exported so lmgr.c can initialize it */
int NumLockMethods;
/*
@ -190,15 +192,15 @@ GetLocksMethodTable(LOCK *lock)
*/
static void
LockMethodInit(LockMethod lockMethodTable,
LOCKMASK *conflictsP,
const LOCKMASK *conflictsP,
int numModes)
{
int i;
lockMethodTable->numLockModes = numModes;
/* copies useless zero element as well as the N lockmodes */
for (i = 0; i <= numModes; i++, conflictsP++)
lockMethodTable->conflictTab[i] = *conflictsP;
for (i = 0; i <= numModes; i++)
lockMethodTable->conflictTab[i] = conflictsP[i];
}
/*
@ -211,8 +213,8 @@ LockMethodInit(LockMethod lockMethodTable,
* TopMemoryContext.
*/
LOCKMETHODID
LockMethodTableInit(char *tabName,
LOCKMASK *conflictsP,
LockMethodTableInit(const char *tabName,
const LOCKMASK *conflictsP,
int numModes,
int maxBackends)
{
@ -244,17 +246,6 @@ LockMethodTableInit(char *tabName,
if (!newLockMethod)
elog(FATAL, "could not initialize lock table \"%s\"", tabName);
/*
* Lock the LWLock for the table (probably not necessary here)
*/
#ifndef EXEC_BACKEND
LWLockAcquire(LockMgrLock, LW_EXCLUSIVE);
#endif
/*
* no zero-th table
*/
NumLockMethods = 1;
/*
* we're first - initialize
*/
@ -263,6 +254,7 @@ LockMethodTableInit(char *tabName,
MemSet(newLockMethod, 0, sizeof(LockMethodData));
newLockMethod->masterLock = LockMgrLock;
newLockMethod->lockmethodid = NumLockMethods;
LockMethodInit(newLockMethod, conflictsP, numModes);
}
/*
@ -311,12 +303,6 @@ LockMethodTableInit(char *tabName,
if (!LockMethodProcLockHash[NumLockMethods-1])
elog(FATAL, "could not initialize lock table \"%s\"", tabName);
/* init data structures */
LockMethodInit(newLockMethod, conflictsP, numModes);
#ifndef EXEC_BACKEND
LWLockRelease(LockMgrLock);
#endif
pfree(shmemName);
return newLockMethod->lockmethodid;

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.415 2004/05/26 04:41:35 neilc Exp $
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.416 2004/05/28 05:13:12 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@ -2189,10 +2189,13 @@ PostgresMain(int argc, char *argv[], const char *username)
/* Set up reference point for stack depth checking */
stack_base_ptr = &stack_base;
if (my_exec_path[0] == '\0' && find_my_exec(argv[0], my_exec_path) < 0)
elog(FATAL,
gettext("%s: could not locate my own executable path"),
argv[0]);
/* Compute paths, if we didn't inherit them from postmaster */
if (my_exec_path[0] == '\0')
{
if (find_my_exec(argv[0], my_exec_path) < 0)
elog(FATAL, "%s: could not locate my own executable path",
argv[0]);
}
if (pkglib_path[0] == '\0')
get_pkglib_path(my_exec_path, pkglib_path);
@ -2547,7 +2550,7 @@ PostgresMain(int argc, char *argv[], const char *username)
on_proc_exit(log_disconnections,0);
}
if (!IsUnderPostmaster || ExecBackend)
if (!IsUnderPostmaster)
{
if (!potential_DataDir)
{
@ -2563,17 +2566,14 @@ PostgresMain(int argc, char *argv[], const char *username)
}
Assert(DataDir);
/* Acquire configuration parameters */
if (IsUnderPostmaster)
/* Acquire configuration parameters, unless inherited from postmaster */
if (!IsUnderPostmaster)
{
#ifdef EXEC_BACKEND
read_nondefault_variables();
#endif
} else
ProcessConfigFile(PGC_POSTMASTER);
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
/* If timezone is not set, determine what the OS uses */
pg_timezone_initialize();
}
/*
* Set up signal handlers and masks.
@ -2918,11 +2918,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (got_SIGHUP)
{
got_SIGHUP = false;
#ifdef EXEC_BACKEND
read_nondefault_variables();
#else
ProcessConfigFile(PGC_SIGHUP);
#endif
}
/*

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.87 2004/05/18 03:36:36 momjian Exp $
* $PostgreSQL: pgsql/src/backend/utils/init/globals.c,v 1.88 2004/05/28 05:13:15 tgl Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
@ -43,11 +43,15 @@ char *DataDir = NULL;
* variable. NULL if no option given and no environment variable set
*/
char OutputFileName[MAXPGPATH];
char OutputFileName[MAXPGPATH]; /* debugging output file */
char my_exec_path[MAXPGPATH]; /* full path to postgres executable */
char postgres_exec_path[MAXPGPATH]; /* full path to backend executable */
char pkglib_path[MAXPGPATH]; /* full path to lib directory */
char my_exec_path[MAXPGPATH]; /* full path to my executable */
char pkglib_path[MAXPGPATH]; /* full path to lib directory */
#ifdef EXEC_BACKEND
char postgres_exec_path[MAXPGPATH]; /* full path to backend */
/* note: currently this is not valid in backend processes */
#endif
BackendId MyBackendId;

View File

@ -6,7 +6,7 @@
* Portions Copyright (c) 2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/access/slru.h,v 1.4 2003/11/29 22:40:55 pgsql Exp $
* $PostgreSQL: pgsql/src/include/access/slru.h,v 1.5 2004/05/28 05:13:17 tgl Exp $
*/
#ifndef SLRU_H
#define SLRU_H
@ -16,35 +16,38 @@
/* exported because lwlock.c needs it */
#define NUM_CLOG_BUFFERS 8
/*
* Note: the separation between SlruLockData and SlruSharedData is purely
* historical; the structs could be combined.
*/
typedef struct SlruLockData
{
LWLockId ControlLock;
/*
* BufferLocks is set during CLOGShmemInit and does not change thereafter.
* The value is automatically inherited by backends via fork, and
* doesn't need to be in shared memory.
*/
LWLockId BufferLocks[NUM_CLOG_BUFFERS]; /* Per-buffer I/O locks */
} SlruLockData;
typedef SlruLockData *SlruLock;
/*
* SlruCtlData is an unshared structure that points to the active information
* in shared memory.
*/
typedef struct SlruCtlData
{
void *shared; /* pointer to SlruSharedData */
SlruLock locks;
/*
* Dir is set during SimpleLruShmemInit and does not change thereafter.
* The value is automatically inherited by backends via fork, and
* doesn't need to be in shared memory.
*/
/*
* Dir is set during SimpleLruShmemInit and does not change thereafter.
* The value is automatically inherited by backends via fork, and
* doesn't need to be in shared memory.
*/
char Dir[MAXPGPATH];
/*
* Decide which of two page numbers is "older" for truncation purposes.
* We need to use comparison of TransactionIds here in order to do the right
* thing with wraparound XID arithmetic.
*/
/*
* Decide which of two page numbers is "older" for truncation purposes.
* We need to use comparison of TransactionIds here in order to do the
* right thing with wraparound XID arithmetic.
*/
bool (*PagePrecedes) (int, int);
} SlruCtlData;

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.33 2003/11/29 22:40:56 pgsql Exp $
* $PostgreSQL: pgsql/src/include/bootstrap/bootstrap.h,v 1.34 2004/05/28 05:13:21 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -34,7 +34,7 @@ typedef struct hashnode
extern Relation boot_reldesc;
extern Form_pg_attribute attrtypes[MAXATTR];
extern int numattr;
extern int BootstrapMain(int ac, char *av[]);
extern int BootstrapMain(int argc, char *argv[]);
extern void index_register(Oid heap, Oid ind, IndexInfo *indexInfo);

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.160 2004/05/18 03:36:44 momjian Exp $
* $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.161 2004/05/28 05:13:24 tgl Exp $
*
* NOTES
* some of the information in this file should be moved to
@ -116,13 +116,13 @@ do { \
* from postmaster/postmaster.c
*/
extern bool ClientAuthInProgress;
extern const bool ExecBackend;
extern int PostmasterMain(int argc, char *argv[]);
#ifdef EXEC_BACKEND
extern void SubPostmasterMain(int argc, char* argv[]);
#endif
extern void ClosePostmasterPorts(bool pgstat_too);
#ifdef EXEC_BACKEND
extern pid_t postmaster_forkexec(int argc, char *argv[]);
extern int SubPostmasterMain(int argc, char *argv[]);
#endif
#define PG_VERSIONSTR "postgres (PostgreSQL) " PG_VERSION "\n"
@ -143,8 +143,10 @@ extern long MyCancelKey;
extern char OutputFileName[];
extern char my_exec_path[];
extern char postgres_exec_path[];
extern char pkglib_path[];
#ifdef EXEC_BACKEND
extern char postgres_exec_path[];
#endif
/*
* done in storage/backendid.h for now.

View File

@ -5,7 +5,7 @@
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.21 2004/03/09 05:11:53 momjian Exp $
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.22 2004/05/28 05:13:25 tgl Exp $
* ----------
*/
#ifndef PGSTAT_H
@ -325,18 +325,6 @@ typedef union PgStat_Msg
} PgStat_Msg;
#ifdef EXEC_BACKEND
typedef enum STATS_PROCESS_TYPE
{
STAT_PROC_BUFFER,
STAT_PROC_COLLECTOR
} STATS_PROCESS_TYPE;
#define PGSTAT_FORK_ARGS int argc, char *argv[]
#else
#define PGSTAT_FORK_ARGS void
#endif
/* ----------
* GUC parameters
* ----------
@ -354,29 +342,22 @@ extern bool pgstat_collect_blocklevel;
extern bool pgstat_is_running;
/* ----------
* Functions called from main
* ----------
*/
#ifdef EXEC_BACKEND
extern void pgstat_main(PGSTAT_FORK_ARGS);
extern void pgstat_mainChild(PGSTAT_FORK_ARGS);
#endif
/* ----------
* Functions called from postmaster
* ----------
*/
#ifdef EXEC_BACKEND
extern void pgstat_init_forkexec_backend(void);
#endif
extern void pgstat_init(void);
extern void pgstat_start(void);
extern bool pgstat_ispgstat(int pid);
extern void pgstat_close_sockets(void);
extern void pgstat_beterm(int pid);
#ifdef EXEC_BACKEND
extern void PgstatBufferMain(int argc, char *argv[]);
extern void PgstatCollectorMain(int argc, char *argv[]);
#endif
/* ----------
* Functions called from backends
* ----------

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.76 2003/12/20 17:31:21 momjian Exp $
* $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.77 2004/05/28 05:13:29 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -223,13 +223,16 @@ typedef struct
LOCK *locks;
} LockData;
extern int NumLockMethods;
/*
* function prototypes
*/
extern void InitLocks(void);
extern LockMethod GetLocksMethodTable(LOCK *lock);
extern LOCKMETHODID LockMethodTableInit(char *tabName, LOCKMASK *conflictsP,
int numModes, int maxBackends);
extern LOCKMETHODID LockMethodTableInit(const char *tabName,
const LOCKMASK *conflictsP,
int numModes, int maxBackends);
extern LOCKMETHODID LockMethodTableRename(LOCKMETHODID lockmethodid);
extern bool LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
TransactionId xid, LOCKMODE lockmode, bool dontWait);

View File

@ -7,7 +7,7 @@
* Copyright (c) 2000-2003, PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.46 2004/05/26 15:07:41 momjian Exp $
* $PostgreSQL: pgsql/src/include/utils/guc.h,v 1.47 2004/05/28 05:13:32 tgl Exp $
*--------------------------------------------------------------------
*/
#ifndef GUC_H
@ -206,8 +206,8 @@ extern ArrayType *GUCArrayAdd(ArrayType *array, const char *name, const char *va
extern ArrayType *GUCArrayDelete(ArrayType *array, const char *name);
#ifdef EXEC_BACKEND
void write_nondefault_variables(GucContext context);
void read_nondefault_variables(void);
extern void write_nondefault_variables(GucContext context);
extern void read_nondefault_variables(void);
#endif
/*