This patch is the next step towards (re)allowing fork/exec.
authorBruce Momjian <bruce@momjian.us>
Sat, 20 Dec 2003 17:31:21 +0000 (17:31 +0000)
committerBruce Momjian <bruce@momjian.us>
Sat, 20 Dec 2003 17:31:21 +0000 (17:31 +0000)
Claudio Natoli

23 files changed:
src/backend/access/transam/xlog.c
src/backend/bootstrap/bootstrap.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/postmaster.c
src/backend/storage/buffer/buf_init.c
src/backend/storage/file/fd.c
src/backend/storage/freespace/freespace.c
src/backend/storage/ipc/ipci.c
src/backend/storage/ipc/pmsignal.c
src/backend/storage/ipc/shmem.c
src/backend/storage/ipc/sinvaladt.c
src/backend/storage/lmgr/lock.c
src/backend/storage/lmgr/lwlock.c
src/backend/storage/lmgr/proc.c
src/backend/tcop/postgres.c
src/include/access/xlogdefs.h
src/include/c.h
src/include/libpq/libpq-be.h
src/include/storage/fd.h
src/include/storage/ipc.h
src/include/storage/lock.h
src/include/storage/lwlock.h
src/include/storage/shmem.h

index 794e392f78dbc906e27ae45213f344af942c1792..1f8eb50795a57e688db7f9b1c07c881ac5286cd0 100644 (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.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));
 
index 94daf943550be32c33211c198a512d2c9041ca78..4820582eb3f99988ac55005a7c05f3cdb016b0f7 100644 (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.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 */ )
        {
index 7eef1163034f215f683f90a11f433d17399415ff..38323f45ba20244a746da78110cf89d653fc661d 100644 (file)
@@ -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};
index b17ade737619969ffed3a84edd6947a0a7f5212a..f0560ce6f7e8777957ea0c516138a6293a39fe09 100644 (file)
@@ -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;
 
@@ -2444,16 +2431,6 @@ BackendFork(Port *port)
                StrNCpy(remote_host, tmphost, sizeof(remote_host));
        }
 
-       /*
-        * 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
@@ -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
index 1c66b950a516b8f052cf82d387e2095654675d9a..1a707568b554d6d07bd566472e0e569a493df6af 100644 (file)
@@ -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
 }
 
 /*
index 78814d77b63362e4fae51ac150673ea6328439d9..4875b7f2bcfe340b7ff92fd5b96189791d0d4924 100644 (file)
@@ -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:
  *
 #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),
index a7bffb5c7338d23e44aed4df304bf841f7c88885..84f5c65c928239a5c82fee8c0e42272457619cf5 100644 (file)
@@ -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);
index 982846843a5231270ff1b7546a7b9e9bf195073e..eaf22a095f1f17f91bb82302c0eb8477d88f3017 100644 (file)
@@ -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
index 6545c748d373bf1eb9f870dae1c8ce7e03d4a463..fb2b2faca0f9467e685194b772c990213977d9ba 100644 (file)
@@ -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));
 }
 
index b4e1439d154d8ca87ae0577d0d243b5259edca37..598597f0aa00e2d4cbb834df148539e4bf2a36c8 100644 (file)
@@ -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;
 }
index ff26f9b86e4746984081107c24219c3cbfcedba2..a50cc4601e5c88dba8f37abb755f5897ffde93c5 100644 (file)
@@ -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;
index 6b450a1d358058bae784a3ad88af948af8442363..8cb25b4ccdd16b8617921f0209a79f15981c11fb 100644 (file)
@@ -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);
index 4142bb5198e23f391ffdcb82ad01df683c5bbc5c..efb3ac4a90fe3e71e651fc865ee9262847dda32b 100644 (file)
@@ -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;
index effe5ac5246a1d407c37c97d519043ae29b747e0..a4bab87e24d1ff0aa3cf18393afa57554e782c87 100644 (file)
@@ -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.
         */
index 0162cdc2d4b18e5c50d109bf8882505fcb1a3e28..66f6dc063c89a65016bbd867aa3ce4a13df8310c 100644 (file)
@@ -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
 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);
 }
-
index 023469c1cc6e7d5ad810cb308d5fd42921dd04c7..057236e4eda83aea0f8a0de4d6c334ae4113d7df 100644 (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/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
  *
index f08f56633d07096eb901144284eb6010816f200e..984bf14fca58f9812e85367d42f1af909c7ad625 100644 (file)
@@ -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"
 
index a7dc475f570dc6955805ebc233359636e4ba8ac2..f011afed86d11c62f0d5561ded899c2907cff11c 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
 #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
index cb81f36a8a44fa0c2991fec045f13aa32a1d8872..35a75a367193b8e5a1b8ba7ef283500f777e6c43 100644 (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/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 */
index fb59cd0200a398fad8851731253ee2bdc84dfbfb..3c2765cc48c8e465f111366ce312883e831b8af4 100644 (file)
@@ -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 */
index a7d66b835ebc53a79b2374ec6d89cc50f6719fb1..2d13e9df11417f137216db617c576925304e71a6 100644 (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.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];
index db5b3d49bb404af86ad4aec0426f90cafc7032f2..34f9c6613c709f9122a054dfb37deab756bede29 100644 (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/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,
index a818f65fe9a84c2d75a404e807e00141e7caa9d6..648cdf8c3a47045811b12fbbec175a7157858e19 100644 (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/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);