aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2003-12-20 17:31:21 +0000
committerBruce Momjian <bruce@momjian.us>2003-12-20 17:31:21 +0000
commitd75b2ec4ebbc7fdb51088e89da47c6523bf2c640 (patch)
tree4f0a12508b01da4d98c663bbdadb4a2e1ae6837a
parent1ee0ddf91df31669ca0d07871d3f5aa88791b78d (diff)
downloadpostgresql-d75b2ec4ebbc7fdb51088e89da47c6523bf2c640.tar.gz
postgresql-d75b2ec4ebbc7fdb51088e89da47c6523bf2c640.zip
This patch is the next step towards (re)allowing fork/exec.
Claudio Natoli
-rw-r--r--src/backend/access/transam/xlog.c27
-rw-r--r--src/backend/bootstrap/bootstrap.c7
-rw-r--r--src/backend/postmaster/pgstat.c4
-rw-r--r--src/backend/postmaster/postmaster.c286
-rw-r--r--src/backend/storage/buffer/buf_init.c6
-rw-r--r--src/backend/storage/file/fd.c15
-rw-r--r--src/backend/storage/freespace/freespace.c22
-rw-r--r--src/backend/storage/ipc/ipci.c28
-rw-r--r--src/backend/storage/ipc/pmsignal.c6
-rw-r--r--src/backend/storage/ipc/shmem.c137
-rw-r--r--src/backend/storage/ipc/sinvaladt.c7
-rw-r--r--src/backend/storage/lmgr/lock.c48
-rw-r--r--src/backend/storage/lmgr/lwlock.c4
-rw-r--r--src/backend/storage/lmgr/proc.c5
-rw-r--r--src/backend/tcop/postgres.c61
-rw-r--r--src/include/access/xlogdefs.h9
-rw-r--r--src/include/c.h9
-rw-r--r--src/include/libpq/libpq-be.h8
-rw-r--r--src/include/storage/fd.h6
-rw-r--r--src/include/storage/ipc.h4
-rw-r--r--src/include/storage/lock.h4
-rw-r--r--src/include/storage/lwlock.h3
-rw-r--r--src/include/storage/shmem.h4
23 files changed, 492 insertions, 218 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 794e392f78d..1f8eb50795a 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -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.128 2003/12/14 00:34:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.129 2003/12/20 17:31:20 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -166,7 +166,7 @@ XLogRecPtr ProcLastRecEnd = {0, 0};
* to update from XLogCtl->Insert.RedoRecPtr if we hold the info_lck;
* see GetRedoRecPtr.
*/
-static XLogRecPtr RedoRecPtr;
+NON_EXEC_STATIC XLogRecPtr RedoRecPtr;
/*----------
* Shared-memory data structures for XLOG control
@@ -231,12 +231,6 @@ typedef struct XLogwrtRqst
XLogRecPtr Flush; /* last byte + 1 to flush */
} XLogwrtRqst;
-typedef struct XLogwrtResult
-{
- XLogRecPtr Write; /* last byte + 1 written out */
- XLogRecPtr Flush; /* last byte + 1 flushed */
-} XLogwrtResult;
-
/*
* Shared state data for XLogInsert.
*/
@@ -404,7 +398,7 @@ static char ControlFilePath[MAXPGPATH];
* Private, possibly out-of-date copy of shared LogwrtResult.
* See discussion above.
*/
-static XLogwrtResult LogwrtResult = {{0, 0}, {0, 0}};
+NON_EXEC_STATIC XLogwrtResult LogwrtResult = {{0, 0}, {0, 0}};
/*
* openLogFile is -1 or a kernel FD for an open log file segment.
@@ -2398,7 +2392,7 @@ XLOGShmemSize(void)
void
XLOGShmemInit(void)
{
- bool found;
+ bool foundXLog, foundCFile;
/* this must agree with space requested by XLOGShmemSize() */
if (XLOGbuffers < MinXLOGbuffers)
@@ -2409,11 +2403,16 @@ XLOGShmemInit(void)
MAXALIGN(sizeof(XLogCtlData) +
sizeof(XLogRecPtr) * XLOGbuffers)
+ BLCKSZ * XLOGbuffers,
- &found);
- Assert(!found);
+ &foundXLog);
ControlFile = (ControlFileData *)
- ShmemInitStruct("Control File", sizeof(ControlFileData), &found);
- Assert(!found);
+ ShmemInitStruct("Control File", sizeof(ControlFileData), &foundCFile);
+
+ if (foundXLog || foundCFile)
+ {
+ /* both should be present or neither */
+ Assert(foundXLog && foundCFile);
+ return;
+ }
memset(XLogCtl, 0, sizeof(XLogCtlData));
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 94daf943550..4820582eb3f 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.170 2003/12/12 18:45:08 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.171 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -347,9 +347,10 @@ BootstrapMain(int argc, char *argv[])
if (!dbname || argc != optind)
usage();
-
- if (IsUnderPostmaster && ExecBackend && MyProc /* ordinary backend */ )
+#ifdef EXEC_BACKEND
+ if (IsUnderPostmaster && MyProc /* ordinary backend */ )
AttachSharedMemoryAndSemaphores();
+#endif
if (!IsUnderPostmaster /* when exec || ExecBackend */ )
{
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 7eef1163034..38323f45ba2 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2003, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.48 2003/11/29 19:51:55 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.49 2003/12/20 17:31:21 momjian Exp $
* ----------
*/
#include "postgres.h"
@@ -71,7 +71,7 @@ bool pgstat_is_running = false;
* Local data
* ----------
*/
-static int pgStatSock = -1;
+NON_EXEC_STATIC int pgStatSock = -1;
static int pgStatPipe[2];
static struct sockaddr_storage pgStatAddr;
static int pgStatPmPipe[2] = {-1, -1};
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index b17ade73761..f0560ce6f7e 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.351 2003/12/01 22:15:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.352 2003/12/20 17:31:21 momjian Exp $
*
* NOTES
*
@@ -273,6 +273,7 @@ static void dummy_handler(SIGNAL_ARGS);
static void CleanupProc(int pid, int exitstatus);
static void LogChildExit(int lev, const char *procname,
int pid, int exitstatus);
+NON_EXEC_STATIC bool BackendInit(Port *port);
static int BackendFork(Port *port);
static void ExitPostmaster(int status);
static void usage(const char *);
@@ -282,10 +283,6 @@ static int ProcessStartupPacket(Port *port, bool SSLdone);
static void processCancelRequest(Port *port, void *pkt);
static int initMasks(fd_set *rmask);
static void report_fork_failure_to_client(Port *port, int errnum);
-enum CAC_state
-{
- CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY
-};
static enum CAC_state canAcceptConnections(void);
static long PostmasterRandom(void);
static void RandomSalt(char *cryptSalt, char *md5Salt);
@@ -298,6 +295,11 @@ postmaster_error(const char *fmt,...)
/* This lets gcc check the format string for consistency. */
__attribute__((format(printf, 1, 2)));
+#ifdef EXEC_BACKEND
+static void
+write_backend_variables(pid_t pid, Port *port);
+#endif
+
#define StartupDataBase() SSDataBase(BS_XLOG_STARTUP)
#define CheckPointDataBase() SSDataBase(BS_XLOG_CHECKPOINT)
#define StartBackgroundWriter() SSDataBase(BS_XLOG_BGWRITER)
@@ -1185,7 +1187,6 @@ initMasks(fd_set *rmask)
static int
ProcessStartupPacket(Port *port, bool SSLdone)
{
- enum CAC_state cac;
int32 len;
void *buf;
ProtocolVersion proto;
@@ -1244,7 +1245,11 @@ ProcessStartupPacket(Port *port, bool SSLdone)
if (proto == CANCEL_REQUEST_CODE)
{
+#ifdef EXEC_BACKEND
+ abort(); /* FIXME: [fork/exec] Whoops. Not handled... yet */
+#else
processCancelRequest(port, buf);
+#endif
return 127; /* XXX */
}
@@ -1435,9 +1440,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
* so now instead of wasting cycles on an authentication exchange.
* (This also allows a pg_ping utility to be written.)
*/
- cac = canAcceptConnections();
-
- switch (cac)
+ switch (port->canAcceptConnections)
{
case CAC_STARTUP:
ereport(FATAL,
@@ -1499,8 +1502,10 @@ processCancelRequest(Port *port, void *pkt)
backendPID)));
return;
}
- else if (ExecBackend)
+#ifdef EXEC_BACKEND
+ else
AttachSharedMemoryAndSemaphores();
+#endif
/* See if we have a matching backend */
@@ -2341,40 +2346,25 @@ split_opts(char **argv, int *argcp, char *s)
}
}
+
/*
- * BackendFork -- perform authentication, and if successful, set up the
- * backend's argument list and invoke backend main().
- *
- * This used to perform an execv() but we no longer exec the backend;
- * it's the same executable as the postmaster.
+ * BackendInit/Fork -- perform authentication [BackendInit], and if successful,
+ * set up the backend's argument list [BackendFork] and invoke
+ * backend main() [or exec in EXEC_BACKEND case]
*
* returns:
* Shouldn't return at all.
* If PostgresMain() fails, return status.
*/
-static int
-BackendFork(Port *port)
+NON_EXEC_STATIC bool
+BackendInit(Port *port)
{
- char **av;
- int maxac;
- int ac;
- char debugbuf[32];
- char protobuf[32];
-
-#ifdef EXEC_BACKEND
- char pbuf[NAMEDATALEN + 256];
-#endif
- int i;
int status;
struct timeval now;
struct timezone tz;
char remote_host[NI_MAXHOST];
char remote_port[NI_MAXSERV];
- /*
- * Let's clean up ourselves as the postmaster child
- */
-
IsUnderPostmaster = true; /* we are a postmaster subprocess now */
ClientAuthInProgress = true; /* limit visibility of log messages */
@@ -2386,9 +2376,6 @@ BackendFork(Port *port)
* Signal handlers setting is moved to tcop/postgres...
*/
- /* Close the postmaster's other sockets */
- ClosePostmasterPorts(true);
-
/* Save port etc. for ps status */
MyProcPort = port;
@@ -2445,16 +2432,6 @@ BackendFork(Port *port)
}
/*
- * PreAuthDelay is a debugging aid for investigating problems in the
- * authentication cycle: it can be set in postgresql.conf to allow
- * time to attach to the newly-forked backend with a debugger. (See
- * also the -W backend switch, which we allow clients to pass through
- * PGOPTIONS, but it is not honored until after authentication.)
- */
- if (PreAuthDelay > 0)
- sleep(PreAuthDelay);
-
- /*
* Ready to begin client interaction. We will give up and exit(0)
* after a time delay, so that a broken client can't hog a connection
* indefinitely. PreAuthDelay doesn't count against the time limit.
@@ -2469,7 +2446,7 @@ BackendFork(Port *port)
status = ProcessStartupPacket(port, false);
if (status != STATUS_OK)
- return 0; /* cancel request processed, or error */
+ return false; /* cancel request processed, or error */
/*
* Now that we have the user and database name, we can set the process
@@ -2506,6 +2483,50 @@ BackendFork(Port *port)
gettimeofday(&now, &tz);
srandom((unsigned int) now.tv_usec);
+#ifdef EXEC_BACKEND
+ ClientAuthInProgress = false; /* client_min_messages is active
+ * now */
+#endif
+ return true;
+}
+
+
+static int
+BackendFork(Port *port)
+{
+ char **av;
+ int maxac;
+ int ac;
+ char debugbuf[32];
+#ifndef EXEC_BACKEND
+ char protobuf[32];
+#endif
+ int i;
+ char tmpExtraOptions[MAXPGPATH];
+
+ /*
+ * Let's clean up ourselves as the postmaster child, and
+ * close the postmaster's other sockets
+ */
+ ClosePostmasterPorts(true);
+
+ /*
+ * PreAuthDelay is a debugging aid for investigating problems in the
+ * authentication cycle: it can be set in postgresql.conf to allow
+ * time to attach to the newly-forked backend with a debugger. (See
+ * also the -W backend switch, which we allow clients to pass through
+ * PGOPTIONS, but it is not honored until after authentication.)
+ */
+ if (PreAuthDelay > 0)
+ sleep(PreAuthDelay);
+
+ port->canAcceptConnections = canAcceptConnections();
+
+#ifndef EXEC_BACKEND
+ if (!BackendInit(port))
+ return -1;
+#endif
+
/* ----------------
* Now, build the argv vector that will be given to PostgresMain.
*
@@ -2540,30 +2561,38 @@ BackendFork(Port *port)
/*
* Pass any backend switches specified with -o in the postmaster's own
- * command line. We assume these are secure. (It's OK to mangle
- * ExtraOptions since we are now in the child process; this won't
- * change the postmaster's copy.)
+ * command line. We assume these are secure.
+ * [Note: now makes a copy to protect against future fork/exec changes]
*/
- split_opts(av, &ac, ExtraOptions);
+ strcpy(tmpExtraOptions,ExtraOptions);
+ split_opts(av, &ac, tmpExtraOptions);
+#ifndef EXEC_BACKEND
/* Tell the backend what protocol the frontend is using. */
snprintf(protobuf, sizeof(protobuf), "-v%u", port->proto);
av[ac++] = protobuf;
+#endif
/*
* Tell the backend it is being called from the postmaster, and which
* database to use. -p marks the end of secure switches.
*/
- av[ac++] = "-p";
#ifdef EXEC_BACKEND
- Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
- /* database name at the end because it might contain commas */
- snprintf(pbuf, sizeof(pbuf), "%d,%d,%lu,%p,%s",
- port->sock, canAcceptConnections(),
- UsedShmemSegID, UsedShmemSegAddr,
- port->database_name);
- av[ac++] = pbuf;
+ write_backend_variables(getpid(),port);
+
+ /* pass data dir before end of secure switches (-p) */
+ av[ac++] = "-D";
+ av[ac++] = DataDir;
+
+ /*
+ * This is totally bogus. We need to pass an arg to -p, but we'll
+ * actually get the dbname by ProcessStartupPacket in the exec'd
+ * process
+ */
+ av[ac++] = "-p";
+ av[ac++] = "FORK_EXEC";
#else
+ av[ac++] = "-p";
av[ac++] = port->database_name;
#endif
@@ -2571,6 +2600,10 @@ BackendFork(Port *port)
* Pass the (insecure) option switches from the connection request.
* (It's OK to mangle port->cmdline_options now.)
*/
+ /* FIXME: [fork/exec] Hmmm.. we won't see these until after we BackendInit.
+ * Should we add code to BackendInit to add these (somehow!) into
+ * the PostgresMain argument list in the EXEC_BACKEND case?
+ */
if (port->cmdline_options)
split_opts(av, &ac, port->cmdline_options);
@@ -2594,17 +2627,21 @@ BackendFork(Port *port)
*/
ereport(DEBUG3,
(errmsg_internal("%s child[%d]: starting with (",
- progname, MyProcPid)));
+ progname, getpid())));
for (i = 0; i < ac; ++i)
ereport(DEBUG3,
(errmsg_internal("\t%s", av[i])));
ereport(DEBUG3,
(errmsg_internal(")")));
+#ifdef EXEC_BACKEND
+ return execv(pg_pathname,av);
+#else
ClientAuthInProgress = false; /* client_min_messages is active
* now */
return (PostgresMain(ac, av, port->user_name));
+#endif
}
/*
@@ -3051,3 +3088,136 @@ postmaster_error(const char *fmt,...)
va_end(ap);
fprintf(stderr, "\n");
}
+
+
+#ifdef EXEC_BACKEND
+
+/*
+ * The following need to be available to the read/write_backend_variables
+ * functions
+ */
+extern XLogRecPtr RedoRecPtr;
+extern XLogwrtResult LogwrtResult;
+extern slock_t *ShmemLock;
+extern slock_t *ShmemIndexLock;
+extern void *ShmemIndexAlloc;
+typedef struct LWLock LWLock;
+extern LWLock *LWLockArray;
+extern slock_t *ProcStructLock;
+extern int pgStatSock;
+
+#define write_var(var,fp) fwrite((void*)&(var),sizeof(var),1,fp)
+#define read_var(var,fp) fread((void*)&(var),sizeof(var),1,fp);
+#define get_tmp_backend_file_name(buf,id) \
+ do { \
+ Assert(DataDir); \
+ sprintf((buf), \
+ "%s/%s/%s.backend_var.%d", \
+ DataDir, \
+ PG_TEMP_FILES_DIR, \
+ PG_TEMP_FILE_PREFIX, \
+ (id)); \
+ } while (0)
+
+static void
+write_backend_variables(pid_t pid, Port *port)
+{
+ char filename[MAXPGPATH];
+ FILE *fp;
+ get_tmp_backend_file_name(filename,pid);
+
+ /* Open file */
+ fp = AllocateFile(filename, PG_BINARY_W);
+ if (!fp)
+ {
+ /* As per OpenTemporaryFile... */
+ char dirname[MAXPGPATH];
+ sprintf(dirname,"%s/%s",DataDir,PG_TEMP_FILES_DIR);
+ mkdir(dirname, S_IRWXU);
+
+ fp = AllocateFile(filename, PG_BINARY_W);
+ if (!fp)
+ {
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not write to file \"%s\": %m", filename)));
+ return;
+ }
+ }
+
+ /* Write vars */
+ write_var(port->sock,fp);
+ write_var(port->proto,fp);
+ write_var(port->laddr,fp);
+ write_var(port->raddr,fp);
+ write_var(port->canAcceptConnections,fp);
+ write_var(MyCancelKey,fp);
+
+ write_var(RedoRecPtr,fp);
+ write_var(LogwrtResult,fp);
+
+ write_var(UsedShmemSegID,fp);
+ write_var(UsedShmemSegAddr,fp);
+
+ write_var(ShmemLock,fp);
+ write_var(ShmemIndexLock,fp);
+ write_var(ShmemVariableCache,fp);
+ write_var(ShmemIndexAlloc,fp);
+
+ write_var(LWLockArray,fp);
+ write_var(ProcStructLock,fp);
+ write_var(pgStatSock,fp);
+
+ /* Release file */
+ FreeFile(fp);
+}
+
+void
+read_backend_variables(pid_t pid, Port *port)
+{
+ char filename[MAXPGPATH];
+ FILE *fp;
+ get_tmp_backend_file_name(filename,pid);
+
+ /* Open file */
+ fp = AllocateFile(filename, PG_BINARY_R);
+ if (!fp)
+ {
+ ereport(ERROR,
+ (errcode_for_file_access(),
+ errmsg("could not read from backend_variables file \"%s\": %m", filename)));
+ return;
+ }
+
+ /* Read vars */
+ read_var(port->sock,fp);
+ read_var(port->proto,fp);
+ read_var(port->laddr,fp);
+ read_var(port->raddr,fp);
+ read_var(port->canAcceptConnections,fp);
+ read_var(MyCancelKey,fp);
+
+ read_var(RedoRecPtr,fp);
+ read_var(LogwrtResult,fp);
+
+ read_var(UsedShmemSegID,fp);
+ read_var(UsedShmemSegAddr,fp);
+
+ read_var(ShmemLock,fp);
+ read_var(ShmemIndexLock,fp);
+ read_var(ShmemVariableCache,fp);
+ read_var(ShmemIndexAlloc,fp);
+
+ read_var(LWLockArray,fp);
+ read_var(ProcStructLock,fp);
+ read_var(pgStatSock,fp);
+
+ /* Release file */
+ FreeFile(fp);
+ if (unlink(filename) != 0)
+ ereport(WARNING,
+ (errcode_for_file_access(),
+ errmsg("could not remove file \"%s\": %m", filename)));
+}
+
+#endif
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index 1c66b950a51..1a707568b55 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.59 2003/12/14 00:34:47 neilc Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.60 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -125,7 +125,9 @@ InitBufferPool(void)
* 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",
@@ -177,7 +179,9 @@ InitBufferPool(void)
/* Init other shared buffer-management stuff */
StrategyInitialize(!foundDescs);
+#ifndef EXEC_BACKEND
LWLockRelease(BufMgrLock);
+#endif
}
/*
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 78814d77b63..4875b7f2bcf 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.104 2003/12/12 18:45:09 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.105 2003/12/20 17:31:21 momjian Exp $
*
* NOTES:
*
@@ -53,11 +53,6 @@
#include "storage/ipc.h"
-/* Filename components for OpenTemporaryFile */
-#define PG_TEMP_FILES_DIR "pgsql_tmp"
-#define PG_TEMP_FILE_PREFIX "pgsql_tmp"
-
-
/*
* Problem: Postgres does a system(ld...) to do dynamic loading.
* This will open several extra files in addition to those used by
@@ -1217,8 +1212,12 @@ RemovePgTempFiles(void)
{
while ((db_de = readdir(db_dir)) != NULL)
{
- if (strcmp(db_de->d_name, ".") == 0 ||
- strcmp(db_de->d_name, "..") == 0)
+ if (strcmp(db_de->d_name, ".") == 0
+#ifndef EXEC_BACKEND
+ /* no PG_TEMP_FILES_DIR in DataDir in non EXEC_BACKEND case */
+ || strcmp(db_de->d_name, "..") == 0
+#endif
+ )
continue;
snprintf(temp_path, sizeof(temp_path),
diff --git a/src/backend/storage/freespace/freespace.c b/src/backend/storage/freespace/freespace.c
index a7bffb5c733..84f5c65c928 100644
--- a/src/backend/storage/freespace/freespace.c
+++ b/src/backend/storage/freespace/freespace.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.27 2003/12/12 18:45:09 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/freespace/freespace.c,v 1.28 2003/12/20 17:31:21 momjian Exp $
*
*
* NOTES:
@@ -180,7 +180,6 @@ typedef struct FSMRelation FSMRelation;
/* Header for whole map */
struct FSMHeader
{
- HTAB *relHash; /* hashtable of FSMRelation entries */
FSMRelation *usageList; /* FSMRelations in usage-recency order */
FSMRelation *usageListTail; /* tail of usage-recency list */
FSMRelation *firstRel; /* FSMRelations in arena storage order */
@@ -218,6 +217,7 @@ int MaxFSMRelations; /* these are set by guc.c */
int MaxFSMPages;
static FSMHeader *FreeSpaceMap; /* points to FSMHeader in shared memory */
+static HTAB *FreeSpaceMapRelHash; /* points to (what used to be) FSMHeader->relHash */
static FSMRelation *lookup_fsm_rel(RelFileNode *rel);
@@ -265,13 +265,15 @@ InitFreeSpaceMap(void)
{
HASHCTL info;
int nchunks;
+ bool found;
/* Create table header */
- FreeSpaceMap = (FSMHeader *) ShmemAlloc(sizeof(FSMHeader));
+ FreeSpaceMap = (FSMHeader *) ShmemInitStruct("Free Space Map Header",sizeof(FSMHeader),&found);
if (FreeSpaceMap == NULL)
ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("insufficient shared memory for free space map")));
+ if (!found)
MemSet(FreeSpaceMap, 0, sizeof(FSMHeader));
/* Create hashtable for FSMRelations */
@@ -279,17 +281,21 @@ InitFreeSpaceMap(void)
info.entrysize = sizeof(FSMRelation);
info.hash = tag_hash;
- FreeSpaceMap->relHash = ShmemInitHash("Free Space Map Hash",
+ FreeSpaceMapRelHash = ShmemInitHash("Free Space Map Hash",
MaxFSMRelations / 10,
MaxFSMRelations,
&info,
(HASH_ELEM | HASH_FUNCTION));
- if (!FreeSpaceMap->relHash)
+ if (!FreeSpaceMapRelHash)
ereport(FATAL,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("insufficient shared memory for free space map")));
+ if (found)
+ return;
+
+
/* Allocate page-storage arena */
nchunks = (MaxFSMPages - 1) / CHUNKPAGES + 1;
/* This check ensures spareChunks will be greater than zero */
@@ -974,7 +980,7 @@ lookup_fsm_rel(RelFileNode *rel)
{
FSMRelation *fsmrel;
- fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
+ fsmrel = (FSMRelation *) hash_search(FreeSpaceMapRelHash,
(void *) rel,
HASH_FIND,
NULL);
@@ -995,7 +1001,7 @@ create_fsm_rel(RelFileNode *rel)
FSMRelation *fsmrel;
bool found;
- fsmrel = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
+ fsmrel = (FSMRelation *) hash_search(FreeSpaceMapRelHash,
(void *) rel,
HASH_ENTER,
&found);
@@ -1050,7 +1056,7 @@ delete_fsm_rel(FSMRelation *fsmrel)
unlink_fsm_rel_usage(fsmrel);
unlink_fsm_rel_storage(fsmrel);
FreeSpaceMap->numRels--;
- result = (FSMRelation *) hash_search(FreeSpaceMap->relHash,
+ result = (FSMRelation *) hash_search(FreeSpaceMapRelHash,
(void *) &(fsmrel->key),
HASH_REMOVE,
NULL);
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 982846843a5..eaf22a095f1 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.59 2003/12/01 21:59:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/ipci.c,v 1.60 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -87,7 +87,7 @@ CreateSharedMemoryAndSemaphores(bool makePrivate,
/*
* Set up shared memory allocation mechanism
*/
- InitShmemAllocation(seghdr);
+ InitShmemAllocation(seghdr, true);
/*
* Now initialize LWLocks, which do shared memory allocation and are
@@ -135,12 +135,36 @@ CreateSharedMemoryAndSemaphores(bool makePrivate,
}
+#ifdef EXEC_BACKEND
/*
* AttachSharedMemoryAndSemaphores
* Attaches to the existing shared resources.
*/
+
+/* FIXME: [fork/exec] This function is starting to look pretty much like
+ CreateSharedMemoryAndSemaphores. Refactor? */
void
AttachSharedMemoryAndSemaphores(void)
{
+ PGShmemHeader *seghdr = PGSharedMemoryCreate(-1,false,-1);
+
+ InitShmemAllocation(seghdr, false);
+
+ InitShmemIndex();
+
+ XLOGShmemInit();
CLOGShmemInit();
+ InitBufferPool();
+
+ InitLocks();
+ InitLockTable(MaxBackends);
+
+ InitProcGlobal(MaxBackends);
+
+ CreateSharedInvalidationState(MaxBackends);
+
+ InitFreeSpaceMap();
+
+ PMSignalInit();
}
+#endif
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 6545c748d37..fb2b2faca0f 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.6 2003/11/29 19:51:56 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/pmsignal.c,v 1.7 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,9 +44,11 @@ static volatile sig_atomic_t *PMSignalFlags;
void
PMSignalInit(void)
{
+ bool found;
PMSignalFlags = (sig_atomic_t *)
- ShmemAlloc(NUM_PMSIGNALS * sizeof(sig_atomic_t));
+ ShmemInitStruct("PMSignalFlags",NUM_PMSIGNALS * sizeof(sig_atomic_t),&found);
+ if (!found)
MemSet(PMSignalFlags, 0, NUM_PMSIGNALS * sizeof(sig_atomic_t));
}
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index b4e1439d154..598597f0aa0 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.74 2003/11/29 19:51:56 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/shmem.c,v 1.75 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -74,7 +74,11 @@ SHMEM_OFFSET ShmemBase; /* start address of shared memory */
static SHMEM_OFFSET ShmemEnd; /* end+1 address of shared memory */
-static slock_t *ShmemLock; /* spinlock for shared memory allocation */
+NON_EXEC_STATIC slock_t *ShmemLock; /* spinlock for shared memory allocation */
+
+NON_EXEC_STATIC slock_t *ShmemIndexLock; /* spinlock for ShmemIndex */
+
+NON_EXEC_STATIC void *ShmemIndexAlloc = NULL; /* Memory actually allocated for ShmemIndex */
static HTAB *ShmemIndex = NULL; /* primary index hashtable for shmem */
@@ -88,7 +92,7 @@ static bool ShmemBootstrap = false; /* bootstrapping shmem index? */
* but we use void to avoid having to include ipc.h in shmem.h.
*/
void
-InitShmemAllocation(void *seghdr)
+InitShmemAllocation(void *seghdr, bool init)
{
PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr;
@@ -97,26 +101,34 @@ InitShmemAllocation(void *seghdr)
ShmemBase = (SHMEM_OFFSET) shmhdr;
ShmemEnd = ShmemBase + shmhdr->totalsize;
- /*
- * Initialize the spinlock used by ShmemAlloc. We have to do the
- * space allocation the hard way, since ShmemAlloc can't be called
- * yet.
- */
- ShmemLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset);
- shmhdr->freeoffset += MAXALIGN(sizeof(slock_t));
- Assert(shmhdr->freeoffset <= shmhdr->totalsize);
-
- SpinLockInit(ShmemLock);
-
- /* ShmemIndex can't be set up yet (need LWLocks first) */
- ShmemIndex = (HTAB *) NULL;
-
- /*
- * Initialize ShmemVariableCache for transaction manager.
- */
- ShmemVariableCache = (VariableCache)
+ if (init)
+ {
+ /*
+ * Initialize the spinlocks used by ShmemAlloc/ShmemInitStruct. We
+ * have to do the space allocation the hard way, since ShmemAlloc
+ * can't be called yet.
+ */
+ ShmemLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset);
+ shmhdr->freeoffset += MAXALIGN(sizeof(slock_t));
+ Assert(shmhdr->freeoffset <= shmhdr->totalsize);
+
+ ShmemIndexLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset);
+ shmhdr->freeoffset += MAXALIGN(sizeof(slock_t));
+ Assert(shmhdr->freeoffset <= shmhdr->totalsize);
+
+ SpinLockInit(ShmemLock);
+ SpinLockInit(ShmemIndexLock);
+
+ /* ShmemIndex can't be set up yet (need LWLocks first) */
+ ShmemIndex = (HTAB *) NULL;
+
+ /*
+ * Initialize ShmemVariableCache for transaction manager.
+ */
+ ShmemVariableCache = (VariableCache)
ShmemAlloc(sizeof(*ShmemVariableCache));
- memset(ShmemVariableCache, 0, sizeof(*ShmemVariableCache));
+ memset(ShmemVariableCache, 0, sizeof(*ShmemVariableCache));
+ }
}
/*
@@ -218,25 +230,28 @@ InitShmemIndex(void)
/*
* Now, create an entry in the hashtable for the index itself.
*/
- MemSet(item.key, 0, SHMEM_INDEX_KEYSIZE);
- strncpy(item.key, "ShmemIndex", SHMEM_INDEX_KEYSIZE);
-
- result = (ShmemIndexEnt *)
- hash_search(ShmemIndex, (void *) &item, HASH_ENTER, &found);
- if (!result)
- ereport(FATAL,
- (errcode(ERRCODE_OUT_OF_MEMORY),
- errmsg("out of shared memory")));
-
- Assert(ShmemBootstrap && !found);
-
- result->location = MAKE_OFFSET(ShmemIndex->hctl);
- result->size = SHMEM_INDEX_SIZE;
-
- ShmemBootstrap = false;
+ if (!IsUnderPostmaster)
+ {
+ MemSet(item.key, 0, SHMEM_INDEX_KEYSIZE);
+ strncpy(item.key, "ShmemIndex", SHMEM_INDEX_KEYSIZE);
+
+ result = (ShmemIndexEnt *)
+ hash_search(ShmemIndex, (void *) &item, HASH_ENTER, &found);
+ if (!result)
+ ereport(FATAL,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("out of shared memory")));
+
+ Assert(ShmemBootstrap && !found);
+
+ result->location = MAKE_OFFSET(ShmemIndex->hctl);
+ result->size = SHMEM_INDEX_SIZE;
+
+ ShmemBootstrap = false;
+ }
/* now release the lock acquired in ShmemInitStruct */
- LWLockRelease(ShmemIndexLock);
+ SpinLockRelease(ShmemIndexLock);
}
/*
@@ -320,21 +335,33 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
strncpy(item.key, name, SHMEM_INDEX_KEYSIZE);
item.location = BAD_LOCATION;
- LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE);
+ SpinLockAcquire(ShmemIndexLock);
if (!ShmemIndex)
{
- /*
- * If the shmem index doesn't exist, we are bootstrapping: we must
- * be trying to init the shmem index itself.
- *
- * Notice that the ShmemIndexLock is held until the shmem index has
- * been completely initialized.
- */
- Assert(strcmp(name, "ShmemIndex") == 0);
- Assert(ShmemBootstrap);
- *foundPtr = FALSE;
- return ShmemAlloc(size);
+ if (IsUnderPostmaster)
+ {
+ /* Must be initializing a (non-standalone) backend */
+ Assert(strcmp(name, "ShmemIndex") == 0);
+ Assert(ShmemBootstrap);
+ Assert(ShmemIndexAlloc);
+ *foundPtr = TRUE;
+ }
+ else
+ {
+ /*
+ * If the shmem index doesn't exist, we are bootstrapping: we must
+ * be trying to init the shmem index itself.
+ *
+ * Notice that the ShmemIndexLock is held until the shmem index has
+ * been completely initialized.
+ */
+ Assert(strcmp(name, "ShmemIndex") == 0);
+ Assert(ShmemBootstrap);
+ *foundPtr = FALSE;
+ ShmemIndexAlloc = ShmemAlloc(size);
+ }
+ return ShmemIndexAlloc;
}
/* look it up in the shmem index */
@@ -343,7 +370,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
if (!result)
{
- LWLockRelease(ShmemIndexLock);
+ SpinLockRelease(ShmemIndexLock);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("out of shared memory")));
@@ -359,7 +386,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
*/
if (result->size != size)
{
- LWLockRelease(ShmemIndexLock);
+ SpinLockRelease(ShmemIndexLock);
elog(WARNING, "ShmemIndex entry size is wrong");
/* let caller print its message too */
@@ -376,7 +403,7 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
/* out of memory */
Assert(ShmemIndex);
hash_search(ShmemIndex, (void *) &item, HASH_REMOVE, NULL);
- LWLockRelease(ShmemIndexLock);
+ SpinLockRelease(ShmemIndexLock);
ereport(WARNING,
(errcode(ERRCODE_OUT_OF_MEMORY),
@@ -389,6 +416,6 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
}
Assert(ShmemIsValid((unsigned long) structPtr));
- LWLockRelease(ShmemIndexLock);
+ SpinLockRelease(ShmemIndexLock);
return structPtr;
}
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index ff26f9b86e4..a50cc4601e5 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.53 2003/11/29 19:51:56 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.54 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -50,10 +50,13 @@ SIBufferInit(int maxBackends)
int segSize;
SISeg *segP;
int i;
+ bool found;
/* Allocate space in shared memory */
segSize = SInvalShmemSize(maxBackends);
- shmInvalBuffer = segP = (SISeg *) ShmemAlloc(segSize);
+ shmInvalBuffer = segP = (SISeg *) ShmemInitStruct("shmInvalBuffer",segSize,&found);
+ if (found)
+ return;
/* Clear message counters, save size of procState array */
segP->minMsgNum = 0;
diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c
index 6b450a1d358..8cb25b4ccdd 100644
--- a/src/backend/storage/lmgr/lock.c
+++ b/src/backend/storage/lmgr/lock.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.130 2003/12/01 21:59:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.131 2003/12/20 17:31:21 momjian Exp $
*
* NOTES
* Outside modules can create a lock table and acquire/release
@@ -153,9 +153,11 @@ PROCLOCK_PRINT(const char *where, const PROCLOCK *proclockP)
* map from lock method id to the lock table structure
*/
static LockMethod LockMethods[MAX_LOCK_METHODS];
-
+static HTAB* LockMethodLockHash[MAX_LOCK_METHODS];
+static HTAB* LockMethodProcLockHash[MAX_LOCK_METHODS];
static int NumLockMethods;
+
/*
* InitLocks -- Init the lock module. Create a private data
* structure for constructing conflict masks.
@@ -245,8 +247,9 @@ LockMethodTableInit(char *tabName,
/*
* Lock the LWLock for the table (probably not necessary here)
*/
+#ifndef EXEC_BACKEND
LWLockAcquire(LockMgrLock, LW_EXCLUSIVE);
-
+#endif
/*
* no zero-th table
*/
@@ -279,15 +282,15 @@ LockMethodTableInit(char *tabName,
hash_flags = (HASH_ELEM | HASH_FUNCTION);
sprintf(shmemName, "%s (lock hash)", tabName);
- newLockMethod->lockHash = ShmemInitHash(shmemName,
+ LockMethodLockHash[NumLockMethods-1] = ShmemInitHash(shmemName,
init_table_size,
max_table_size,
&info,
hash_flags);
- if (!newLockMethod->lockHash)
+ if (!LockMethodLockHash[NumLockMethods-1])
elog(FATAL, "could not initialize lock table \"%s\"", tabName);
- Assert(newLockMethod->lockHash->hash == tag_hash);
+ Assert(LockMethodLockHash[NumLockMethods-1]->hash == tag_hash);
/*
* allocate a hash table for PROCLOCK structs. This is used to store
@@ -299,20 +302,21 @@ LockMethodTableInit(char *tabName,
hash_flags = (HASH_ELEM | HASH_FUNCTION);
sprintf(shmemName, "%s (proclock hash)", tabName);
- newLockMethod->proclockHash = ShmemInitHash(shmemName,
+ LockMethodProcLockHash[NumLockMethods-1] = ShmemInitHash(shmemName,
init_table_size,
max_table_size,
&info,
hash_flags);
- if (!newLockMethod->proclockHash)
+ 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;
@@ -449,8 +453,8 @@ LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
/*
* Find or create a lock with this tag
*/
- Assert(lockMethodTable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(lockMethodTable->lockHash,
+ Assert(LockMethodLockHash[lockmethodid]->hash == tag_hash);
+ lock = (LOCK *) hash_search(LockMethodLockHash[lockmethodid],
(void *) locktag,
HASH_ENTER, &found);
if (!lock)
@@ -497,7 +501,7 @@ LockAcquire(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
/*
* Find or create a proclock entry with this tag
*/
- proclockTable = lockMethodTable->proclockHash;
+ proclockTable = LockMethodProcLockHash[lockmethodid];
proclock = (PROCLOCK *) hash_search(proclockTable,
(void *) &proclocktag,
HASH_ENTER, &found);
@@ -988,8 +992,8 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
/*
* Find a lock with this tag
*/
- Assert(lockMethodTable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(lockMethodTable->lockHash,
+ Assert(LockMethodLockHash[lockmethodid]->hash == tag_hash);
+ lock = (LOCK *) hash_search(LockMethodLockHash[lockmethodid],
(void *) locktag,
HASH_FIND, NULL);
@@ -1014,7 +1018,7 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
proclocktag.proc = MAKE_OFFSET(MyProc);
TransactionIdStore(xid, &proclocktag.xid);
- proclockTable = lockMethodTable->proclockHash;
+ proclockTable = LockMethodProcLockHash[lockmethodid];
proclock = (PROCLOCK *) hash_search(proclockTable,
(void *) &proclocktag,
HASH_FIND_SAVE, NULL);
@@ -1086,8 +1090,8 @@ LockRelease(LOCKMETHODID lockmethodid, LOCKTAG *locktag,
* if there's no one waiting in the queue, we just released the
* last lock on this object. Delete it from the lock table.
*/
- Assert(lockMethodTable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(lockMethodTable->lockHash,
+ Assert(LockMethodLockHash[lockmethodid]->hash == tag_hash);
+ lock = (LOCK *) hash_search(LockMethodLockHash[lockmethodid],
(void *) &(lock->tag),
HASH_REMOVE,
NULL);
@@ -1269,7 +1273,7 @@ LockReleaseAll(LOCKMETHODID lockmethodid, PGPROC *proc,
/*
* remove the proclock entry from the hashtable
*/
- proclock = (PROCLOCK *) hash_search(lockMethodTable->proclockHash,
+ proclock = (PROCLOCK *) hash_search(LockMethodProcLockHash[lockmethodid],
(void *) proclock,
HASH_REMOVE,
NULL);
@@ -1287,8 +1291,8 @@ LockReleaseAll(LOCKMETHODID lockmethodid, PGPROC *proc,
* lock object.
*/
LOCK_PRINT("LockReleaseAll: deleting", lock, 0);
- Assert(lockMethodTable->lockHash->hash == tag_hash);
- lock = (LOCK *) hash_search(lockMethodTable->lockHash,
+ Assert(LockMethodLockHash[lockmethodid]->hash == tag_hash);
+ lock = (LOCK *) hash_search(LockMethodLockHash[lockmethodid],
(void *) &(lock->tag),
HASH_REMOVE, NULL);
if (!lock)
@@ -1367,7 +1371,7 @@ GetLockStatusData(void)
LWLockAcquire(LockMgrLock, LW_EXCLUSIVE);
- proclockTable = LockMethods[DEFAULT_LOCKMETHOD]->proclockHash;
+ proclockTable = LockMethodProcLockHash[DEFAULT_LOCKMETHOD];
data->nelements = i = proclockTable->hctl->nentries;
@@ -1480,7 +1484,7 @@ DumpAllLocks(void)
if (!lockMethodTable)
return;
- proclockTable = lockMethodTable->proclockHash;
+ proclockTable = LockMethodProcLockHash[lockmethodid];
if (proc->waitLock)
LOCK_PRINT("DumpAllLocks: waiting on", proc->waitLock, 0);
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 4142bb5198e..efb3ac4a90f 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.18 2003/11/29 19:51:57 pgsql Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/lwlock.c,v 1.19 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -43,7 +43,7 @@ typedef struct LWLock
* the pointer by fork from the postmaster. LWLockIds are indexes into
* the array.
*/
-static LWLock *LWLockArray = NULL;
+NON_EXEC_STATIC LWLock *LWLockArray = NULL;
/* shared counter for dynamic allocation of LWLockIds */
static int *LWLockCounter;
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index effe5ac5246..a4bab87e24d 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.140 2003/12/12 18:45:09 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.141 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -66,7 +66,7 @@ PGPROC *MyProc = NULL;
* relatively infrequently (only at backend startup or shutdown) and not for
* very long, so a spinlock is okay.
*/
-static slock_t *ProcStructLock = NULL;
+NON_EXEC_STATIC slock_t *ProcStructLock = NULL;
static PROC_HDR *ProcGlobal = NULL;
@@ -248,6 +248,7 @@ InitProcess(void)
MyProc->waitHolder = NULL;
SHMQueueInit(&(MyProc->procHolders));
+
/*
* Arrange to clean up at backend exit.
*/
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index 0162cdc2d4b..66f6dc063c8 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.379 2003/12/01 22:15:37 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.380 2003/12/20 17:31:21 momjian Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
@@ -68,6 +68,10 @@
extern int optind;
extern char *optarg;
+#ifdef EXEC_BACKEND
+extern bool BackendInit(Port*);
+extern void read_backend_variables(pid_t, Port*);
+#endif
/* ----------------
* global variables
@@ -2052,7 +2056,6 @@ PostgresMain(int argc, char *argv[], const char *username)
* initialize globals (already done if under postmaster, but not if
* standalone; cheap enough to do over)
*/
-
MyProcPid = getpid();
/*
@@ -2060,7 +2063,7 @@ PostgresMain(int argc, char *argv[], const char *username)
*
* If we are running under the postmaster, this is done already.
*/
- if (!IsUnderPostmaster)
+ if (!IsUnderPostmaster /* when exec || ExecBackend */)
MemoryContextInit();
set_ps_display("startup");
@@ -2268,7 +2271,6 @@ PostgresMain(int argc, char *argv[], const char *username)
break;
case 'p':
-
/*
* p - special flag passed if backend was forked by a
* postmaster.
@@ -2276,23 +2278,11 @@ PostgresMain(int argc, char *argv[], const char *username)
if (secure)
{
#ifdef EXEC_BACKEND
- char *p;
- int i;
- int PMcanAcceptConnections; /* will eventually be
- * global or static,
- * when fork */
-
- sscanf(optarg, "%d,%d,%lu,%p,",
- &MyProcPort->sock, &PMcanAcceptConnections,
- &UsedShmemSegID, &UsedShmemSegAddr);
- /* Grab dbname as last param */
- for (i = 0, p = optarg - 1; i < 4 && p; i++)
- p = strchr(p + 1, ',');
- if (i == 4 && p)
- dbname = strdup(p + 1);
+ IsUnderPostmaster = true;
#else
dbname = strdup(optarg);
#endif
+
secure = false; /* subsequent switches are NOT
* secure */
ctx = PGC_BACKEND;
@@ -2477,7 +2467,7 @@ PostgresMain(int argc, char *argv[], const char *username)
SetConfigOption("log_statement_stats", "false", ctx, gucsource);
}
- if (!IsUnderPostmaster)
+ if (!IsUnderPostmaster || ExecBackend)
{
if (!potential_DataDir)
{
@@ -2497,10 +2487,27 @@ PostgresMain(int argc, char *argv[], const char *username)
if (IsUnderPostmaster)
{
#ifdef EXEC_BACKEND
+ Port *port =(Port*)malloc(sizeof(Port));
+ if (port == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_OUT_OF_MEMORY),
+ errmsg("insufficient memory to allocate port")));
+
read_nondefault_variables();
+ read_backend_variables(getpid(),port);
+
+ /* FIXME: [fork/exec] Ugh */
+ load_hba();
+ load_ident();
+ load_user();
+ load_group();
+
+ if (!BackendInit(port))
+ return -1;
+
+ dbname = port->database_name;
#endif
- }
- else
+ } else
ProcessConfigFile(PGC_POSTMASTER);
/*
@@ -2517,7 +2524,6 @@ PostgresMain(int argc, char *argv[], const char *username)
* course, this isn't an issue for signals that are locally generated,
* such as SIGALRM and SIGPIPE.)
*/
-
pqsignal(SIGHUP, SigHupHandler); /* set flag to read config file */
pqsignal(SIGINT, StatementCancelHandler); /* cancel current query */
pqsignal(SIGTERM, die); /* cancel current query and exit */
@@ -2565,10 +2571,12 @@ PostgresMain(int argc, char *argv[], const char *username)
errmsg("invalid command-line arguments for server process"),
errhint("Try \"%s --help\" for more information.", argv[0])));
}
- BaseInit();
-#ifdef EXECBACKEND
+#ifdef EXEC_BACKEND
AttachSharedMemoryAndSemaphores();
#endif
+ XLOGPathInit();
+
+ BaseInit();
}
else
{
@@ -2845,7 +2853,11 @@ 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
}
/*
@@ -3199,4 +3211,3 @@ ShowUsage(const char *title)
pfree(str.data);
}
-
diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h
index 023469c1cc6..057236e4eda 100644
--- a/src/include/access/xlogdefs.h
+++ b/src/include/access/xlogdefs.h
@@ -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/access/xlogdefs.h,v 1.10 2003/11/29 22:40:55 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/access/xlogdefs.h,v 1.11 2003/12/20 17:31:21 momjian Exp $
*/
#ifndef XLOG_DEFS_H
#define XLOG_DEFS_H
@@ -33,6 +33,13 @@ typedef struct XLogRecPtr
uint32 xrecoff; /* byte offset of location in log file */
} XLogRecPtr;
+typedef struct XLogwrtResult
+{
+ XLogRecPtr Write; /* last byte + 1 written out */
+ XLogRecPtr Flush; /* last byte + 1 flushed */
+} XLogwrtResult;
+
+
/*
* Macros for comparing XLogRecPtrs
*
diff --git a/src/include/c.h b/src/include/c.h
index f08f56633d0..984bf14fca5 100644
--- a/src/include/c.h
+++ b/src/include/c.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/c.h,v 1.157 2003/11/29 22:40:53 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/c.h,v 1.158 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -793,6 +793,13 @@ extern int fdatasync(int fildes);
#define HAVE_STRTOULL 1
#endif
+/* EXEC_BACKEND defines */
+#ifdef EXEC_BACKEND
+#define NON_EXEC_STATIC
+#else
+#define NON_EXEC_STATIC static
+#endif
+
/* /port compatibility functions */
#include "port.h"
diff --git a/src/include/libpq/libpq-be.h b/src/include/libpq/libpq-be.h
index a7dc475f570..f011afed86d 100644
--- a/src/include/libpq/libpq-be.h
+++ b/src/include/libpq/libpq-be.h
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.38 2003/11/29 22:41:03 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/libpq/libpq-be.h,v 1.39 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,11 @@
#endif
+typedef enum CAC_state
+{
+ CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY
+} CAC_state;
+
/*
* This is used by the postmaster in its communication with frontends. It
* contains all state information needed during this communication before the
@@ -42,6 +47,7 @@ typedef struct Port
ProtocolVersion proto; /* FE/BE protocol version */
SockAddr laddr; /* local addr (postmaster) */
SockAddr raddr; /* remote addr (client) */
+ CAC_state canAcceptConnections; /* postmaster connection status */
/*
* Information that needs to be saved from the startup packet and
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index cb81f36a8a4..35a75a36719 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -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/fd.h,v 1.40 2003/11/29 22:41:13 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/storage/fd.h,v 1.41 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -77,4 +77,8 @@ extern void RemovePgTempFiles(void);
extern int pg_fsync(int fd);
extern int pg_fdatasync(int fd);
+/* Filename components for OpenTemporaryFile */
+#define PG_TEMP_FILES_DIR "pgsql_tmp"
+#define PG_TEMP_FILE_PREFIX "pgsql_tmp"
+
#endif /* FD_H */
diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h
index fb59cd0200a..3c2765cc48c 100644
--- a/src/include/storage/ipc.h
+++ b/src/include/storage/ipc.h
@@ -11,7 +11,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/ipc.h,v 1.63 2003/12/12 18:45:10 petere Exp $
+ * $PostgreSQL: pgsql/src/include/storage/ipc.h,v 1.64 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -32,6 +32,8 @@ extern void on_exit_reset(void);
extern void CreateSharedMemoryAndSemaphores(bool makePrivate,
int maxBackends,
int port);
+#ifdef EXEC_BACKEND
extern void AttachSharedMemoryAndSemaphores(void);
+#endif
#endif /* IPC_H */
diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h
index a7d66b835eb..2d13e9df114 100644
--- a/src/include/storage/lock.h
+++ b/src/include/storage/lock.h
@@ -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.75 2003/12/01 21:59:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/lock.h,v 1.76 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -86,8 +86,6 @@ typedef uint16 LOCKMETHODID;
*/
typedef struct LockMethodData
{
- HTAB *lockHash;
- HTAB *proclockHash;
LOCKMETHODID lockmethodid;
int numLockModes;
LOCKMASK conflictTab[MAX_LOCKMODES];
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index db5b3d49bb4..34f9c6613c7 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -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/lwlock.h,v 1.9 2003/11/29 22:41:13 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/storage/lwlock.h,v 1.10 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,7 +29,6 @@ typedef enum LWLockId
LockMgrLock,
OidGenLock,
XidGenLock,
- ShmemIndexLock,
SInvalLock,
FreeSpaceLock,
MMCacheLock,
diff --git a/src/include/storage/shmem.h b/src/include/storage/shmem.h
index a818f65fe9a..648cdf8c3a4 100644
--- a/src/include/storage/shmem.h
+++ b/src/include/storage/shmem.h
@@ -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/shmem.h,v 1.40 2003/11/29 22:41:13 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/storage/shmem.h,v 1.41 2003/12/20 17:31:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -61,7 +61,7 @@ typedef struct SHM_QUEUE
} SHM_QUEUE;
/* shmem.c */
-extern void InitShmemAllocation(void *seghdr);
+extern void InitShmemAllocation(void *seghdr, bool init);
extern void *ShmemAlloc(Size size);
extern bool ShmemIsValid(unsigned long addr);
extern void InitShmemIndex(void);