Final rearrangement of main postgresql child process (ie.
authorBruce Momjian <bruce@momjian.us>
Tue, 6 Jan 2004 23:15:22 +0000 (23:15 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 6 Jan 2004 23:15:22 +0000 (23:15 +0000)
BackendFork/SSDataBase/pgstat) startup, to allow fork/exec calls to
closely mimic (the soon to be provided) Win32 CreateProcess equivalent
calls.

Claudio Natoli

src/backend/bootstrap/bootstrap.c
src/backend/main/main.c
src/backend/postmaster/pgstat.c
src/backend/postmaster/postmaster.c
src/backend/tcop/postgres.c
src/include/miscadmin.h

index f42c071195fbadff32b554404b02e01cce309ed1..b21f4cc80659a45de79102b36835b74acbd670b5 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.172 2003/12/25 03:52:50 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/bootstrap/bootstrap.c,v 1.173 2004/01/06 23:15:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -51,7 +51,7 @@
 #ifdef EXEC_BACKEND
 typedef struct Port Port;
 extern void SSDataBaseInit(int);
-extern void read_backend_variables(pid_t, Port*);
+extern void read_backend_variables(unsigned long, Port*);
 #endif
 
 extern int Int_yyparse(void);
@@ -231,6 +231,9 @@ BootstrapMain(int argc, char *argv[])
    int         flag;
    int         xlogop = BS_XLOG_NOP;
    char       *potential_DataDir = NULL;
+#ifdef EXEC_BACKEND
+   unsigned long   backendID = 0;
+#endif
 
    /*
     * initialize globals
@@ -291,10 +294,15 @@ BootstrapMain(int argc, char *argv[])
                break;
            case 'p':
 #ifdef EXEC_BACKEND
-               IsUnderPostmaster = true;
+               {
+                   char buf[MAXPGPATH];
+                   IsUnderPostmaster = true;
+                   sscanf(optarg,"%lu,%s",&backendID,buf);
+                   dbname = strdup(buf);
+               }
 #endif
                dbname = strdup(optarg);
-                   break;
+               break;
            case 'B':
                SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);
                break;
@@ -363,7 +371,7 @@ BootstrapMain(int argc, char *argv[])
    {
 #ifdef EXEC_BACKEND
        read_nondefault_variables();
-       read_backend_variables(getpid(),NULL);
+       read_backend_variables(backendID,NULL);
 
        SSDataBaseInit(xlogop);
 #endif
@@ -431,11 +439,11 @@ BootstrapMain(int argc, char *argv[])
        switch (xlogop)
        {
            case BS_XLOG_BGWRITER:
-               InitDummyProcess(DUMMY_PROC_BGWRITER);  
+               InitDummyProcess(DUMMY_PROC_BGWRITER);
                break;
-       
+
            default:
-               InitDummyProcess(DUMMY_PROC_DEFAULT);   
+               InitDummyProcess(DUMMY_PROC_DEFAULT);
                break;
        }
    }
index 84036314cd15fb331c229f8ce5480903ac0107f4..b8dffc430a10c6e36503b78f13e3a97246649ee9 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/main/main.c,v 1.69 2003/12/25 03:52:50 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/main/main.c,v 1.70 2004/01/06 23:15:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -203,9 +203,9 @@ main(int argc, char *argv[])
 
    /*
     * Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain,
-    * pgstat_main, pgstat_mainChild or BootstrapMain depending on the
-    * program name (and possibly first argument) we were called with.
-    * The lack of consistency here is historical.
+    * SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain
+    * depending on the program name (and possibly first argument) we
+    * were called with. The lack of consistency here is historical.
     */
    len = strlen(new_argv[0]);
 
@@ -223,6 +223,16 @@ main(int argc, char *argv[])
        exit(BootstrapMain(argc - 1, new_argv + 1));
 
 #ifdef EXEC_BACKEND
+   /*
+    * If the first argument is "-forkexec", then invoke SubPostmasterMain. Note
+    * we remove "-forkexec" from the arguments passed on to SubPostmasterMain.
+    */
+   if (argc > 1 && strcmp(new_argv[1], "-forkexec") == 0)
+   {
+       SubPostmasterMain(argc - 2, new_argv + 2);
+       exit(0);
+   }
+
    /*
     * If the first argument is "-statBuf", then invoke pgstat_main. Note
     * we remove "-statBuf" from the arguments passed on to pgstat_main.
index 90689d2f4e63c5625d8353ab9afe9021de427abe..bbe003edfb21092ac201c6651592c21dcb820358 100644 (file)
@@ -13,7 +13,7 @@
  *
  * Copyright (c) 2001-2003, PostgreSQL Global Development Group
  *
- * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.50 2003/12/25 03:52:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.51 2004/01/06 23:15:22 momjian Exp $
  * ----------
  */
 #include "postgres.h"
@@ -107,7 +107,7 @@ static char pgStat_fname[MAXPGPATH];
  * ----------
  */
 #ifdef EXEC_BACKEND
-static void pgstat_exec(STATS_PROCESS_TYPE procType);
+static pid_t pgstat_forkexec(STATS_PROCESS_TYPE procType);
 static void pgstat_parseArgs(PGSTAT_FORK_ARGS);
 #endif
 NON_EXEC_STATIC void pgstat_main(PGSTAT_FORK_ARGS);
@@ -337,15 +337,16 @@ startup_failed:
 #ifdef EXEC_BACKEND
 
 /* ----------
- * pgstat_exec() -
+ * pgstat_forkexec() -
  *
- * Used to format up the arglist for, and exec, statistics
+ * Used to format up the arglist for, then fork and exec, statistics
  * (buffer and collector) processes
  *
  */
-static void
-pgstat_exec(STATS_PROCESS_TYPE procType)
+static pid_t
+pgstat_forkexec(STATS_PROCESS_TYPE procType)
 {
+   pid_t pid;
    char *av[11];
    int ac = 0, bufc = 0, i;
    char pgstatBuf[8][MAXPGPATH];
@@ -387,9 +388,12 @@ pgstat_exec(STATS_PROCESS_TYPE procType)
    av[ac++] = NULL;
    Assert(ac <= lengthof(av));
 
-   if (execv(pg_pathname,av) == -1)
+   /* Fire off execv in child */
+   if ((pid = fork()) == 0 && (execv(pg_pathname,av) == -1))
        /* FIXME: [fork/exec] suggestions for what to do here? Can't call elog... */
-       Assert(false);
+       abort();
+
+   return pid; /* Parent returns pid */
 }
 
 
@@ -479,7 +483,11 @@ pgstat_start(void)
    beos_before_backend_startup();
 #endif
 
+#ifdef EXEC_BACKEND
+   switch ((pgStatSock = (int) pgstat_forkexec(STAT_PROC_BUFFER)))
+#else
    switch ((pgStatPid = (int) fork()))
+#endif
    {
        case -1:
 #ifdef __BEOS__
@@ -490,32 +498,27 @@ pgstat_start(void)
                    (errmsg("could not fork statistics buffer: %m")));
            return;
 
+#ifndef EXEC_BACKEND
        case 0:
+           /* in postmaster child ... */
+#ifdef __BEOS__
+           /* Specific beos actions after backend startup */
+           beos_backend_startup();
+#endif
+           /* Close the postmaster's sockets, except for pgstat link */
+           ClosePostmasterPorts(false);
+
+           /* Drop our connection to postmaster's shared memory, as well */
+           PGSharedMemoryDetach();
+
+           pgstat_main();
            break;
+#endif
 
        default:
            pgstat_is_running = true;
            return;
    }
-
-   /* in postmaster child ... */
-
-#ifdef __BEOS__
-   /* Specific beos actions after backend startup */
-   beos_backend_startup();
-#endif
-
-   /* Close the postmaster's sockets, except for pgstat link */
-   ClosePostmasterPorts(false);
-
-   /* Drop our connection to postmaster's shared memory, as well */
-   PGSharedMemoryDetach();
-
-#ifdef EXEC_BACKEND
-   pgstat_exec(STAT_PROC_BUFFER);
-#else
-   pgstat_main();
-#endif
 }
 
 
@@ -1385,28 +1388,31 @@ pgstat_main(PGSTAT_FORK_ARGS)
        exit(1);
    }
 
+#ifdef EXEC_BACKEND
+   /* child becomes collector process */
+   switch (pgstat_forkexec(STAT_PROC_COLLECTOR))
+#else
    switch (fork())
+#endif
    {
        case -1:
            ereport(LOG,
                    (errmsg("could not fork statistics collector: %m")));
            exit(1);
 
+#ifndef EXEC_BACKEND
        case 0:
            /* child becomes collector process */
-#ifdef EXEC_BACKEND
-           pgstat_exec(STAT_PROC_COLLECTOR);
-#else
            pgstat_mainChild();
+           break;
 #endif
-           exit(0);
 
        default:
            /* parent becomes buffer process */
            closesocket(pgStatPipe[0]);
            pgstat_recvbuffer();
-           exit(0);
    }
+   exit(0);
 }
 
 
index cd654e1ffcfcfe7cd20f38d283b723156c96f6f2..9d648b8067d25196476265bfc702f206dc525fe9 100644 (file)
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.353 2003/12/25 03:52:51 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.354 2004/01/06 23:15:22 momjian Exp $
  *
  * NOTES
  *
@@ -273,8 +273,8 @@ 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 BackendInit(Port *port);
+static int  BackendRun(Port *port);
 static void ExitPostmaster(int status);
 static void usage(const char *);
 static int ServerLoop(void);
@@ -297,8 +297,11 @@ postmaster_error(const char *fmt,...)
 __attribute__((format(printf, 1, 2)));
 
 #ifdef EXEC_BACKEND
-void read_backend_variables(pid_t pid, Port *port);
-static void write_backend_variables(pid_t pid, Port *port);
+static pid_t Backend_forkexec(Port *port);
+
+static unsigned long tmpBackendFileNum = 0;
+void read_backend_variables(unsigned long id, Port *port);
+static bool write_backend_variables(Port *port);
 #endif
 
 #define StartupDataBase()      SSDataBase(BS_XLOG_STARTUP)
@@ -916,7 +919,7 @@ pmdaemonize(int argc, char *argv[])
 #endif
 
 #ifdef LINUX_PROFILE
-   /* see comments in BackendStartup */
+   /* see comments in BackendRun */
    getitimer(ITIMER_PROF, &prof_itimer);
 #endif
 
@@ -1310,7 +1313,7 @@ ProcessStartupPacket(Port *port, bool SSLdone)
     * Now fetch parameters out of startup packet and save them into the
     * Port structure.  All data structures attached to the Port struct
     * must be allocated in TopMemoryContext so that they won't disappear
-    * when we pass them to PostgresMain (see BackendFork).  We need not
+    * when we pass them to PostgresMain (see BackendRun).  We need not
     * worry about leaking this storage on failure, since we aren't in the
     * postmaster process anymore.
     */
@@ -2235,12 +2238,14 @@ BackendStartup(Port *port)
    beos_before_backend_startup();
 #endif
 
+   port->canAcceptConnections = canAcceptConnections();
+#ifdef EXEC_BACKEND
+   pid = Backend_forkexec(port);
+#else
    pid = fork();
 
    if (pid == 0)               /* child */
    {
-       int         status;
-
 #ifdef LINUX_PROFILE
        setitimer(ITIMER_PROF, &prof_itimer, NULL);
 #endif
@@ -2251,13 +2256,9 @@ BackendStartup(Port *port)
 #endif
        free(bn);
 
-       status = BackendFork(port);
-
-       if (status != 0)
-           ereport(LOG,
-                   (errmsg("connection startup failed")));
-       proc_exit(status);
+       proc_exit(BackendRun(port));
    }
+#endif
 
    /* in parent, error */
    if (pid < 0)
@@ -2349,15 +2350,15 @@ split_opts(char **argv, int *argcp, char *s)
 
 
 /*
- * 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]
+ * BackendInit/Run -- perform authentication [BackendInit], and if successful,
+ *              set up the backend's argument list [BackendRun] and invoke
+ *              backend main()
  *
  * returns:
  *     Shouldn't return at all.
  *     If PostgresMain() fails, return status.
  */
-NON_EXEC_STATIC bool
+static void
 BackendInit(Port *port)
 {
    int         status;
@@ -2447,7 +2448,11 @@ BackendInit(Port *port)
    status = ProcessStartupPacket(port, false);
 
    if (status != STATUS_OK)
-       return false;               /* cancel request processed, or error */
+   {
+       ereport(LOG,
+               (errmsg("connection startup failed")));
+       proc_exit(status);
+   }
 
    /*
     * Now that we have the user and database name, we can set the process
@@ -2483,27 +2488,18 @@ BackendInit(Port *port)
    random_seed = 0;
    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)
+BackendRun(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
@@ -2521,12 +2517,9 @@ BackendFork(Port *port)
    if (PreAuthDelay > 0)
        sleep(PreAuthDelay);
 
-   port->canAcceptConnections = canAcceptConnections();
+   /* Will exit on failure */
+   BackendInit(port);
 
-#ifndef EXEC_BACKEND
-   if (!BackendInit(port))
-       return -1;
-#endif
 
    /* ----------------
     * Now, build the argv vector that will be given to PostgresMain.
@@ -2563,48 +2556,30 @@ BackendFork(Port *port)
    /*
     * Pass any backend switches specified with -o in the postmaster's own
     * command line.  We assume these are secure.
-    * [Note: now makes a copy to protect against future fork/exec changes]
     */
-   strcpy(tmpExtraOptions,ExtraOptions);
-   split_opts(av, &ac, tmpExtraOptions);
+   split_opts(av, &ac, ExtraOptions);
 
-#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.
-    */
 #ifdef EXEC_BACKEND
-   write_backend_variables(getpid(),port);
-
    /* pass data dir before end of secure switches (-p) */
    av[ac++] = "-D";
    av[ac++] = DataDir;
+#endif
 
    /*
-    * 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
+    * 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";
-   av[ac++] = "FORK_EXEC";
-#else
-   av[ac++] = "-p";
    av[ac++] = port->database_name;
-#endif
 
    /*
     * 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);
 
@@ -2620,7 +2595,9 @@ BackendFork(Port *port)
     * username isn't lost either; see ProcessStartupPacket().
     */
    MemoryContextSwitchTo(TopMemoryContext);
+#ifndef EXEC_BACKEND
    MemoryContextDelete(PostmasterContext);
+#endif
    PostmasterContext = NULL;
 
    /*
@@ -2635,16 +2612,105 @@ BackendFork(Port *port)
    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
 }
 
+
+#ifdef EXEC_BACKEND
+
+
+/*
+ * SubPostmasterMain -- prepare the fork/exec'd process to be in an equivalent
+ *         state (for calling BackendRun) as a forked process.
+ *
+ * returns:
+ *     Shouldn't return at all.
+ */
+void
+SubPostmasterMain(int argc, char* argv[])
+{
+   unsigned long   backendID;
+   Port            port;
+
+   memset((void*)&port, 0, sizeof(Port));
+   Assert(argc == 2);
+
+   /* Setup global context */
+   MemoryContextInit();
+   InitializeGUCOptions();
+
+   /* Parse passed-in context */
+   argc = 0;
+   backendID       = (unsigned long)atol(argv[argc++]);
+   DataDir         = strdup(argv[argc++]);
+
+   /* Read in file-based context */
+   read_nondefault_variables();
+   read_backend_variables(backendID,&port);
+
+   /* FIXME: [fork/exec] Ugh */
+   load_hba();
+   load_ident();
+   load_user();
+   load_group();
+
+   /* Run backend */
+   proc_exit(BackendRun(&port));
+}
+
+
+/*
+ * Backend_forkexec -- fork/exec off a backend process
+ *
+ * returns:
+ *     the pid of the fork/exec'd process
+ */
+static pid_t
+Backend_forkexec(Port *port)
+{
+   pid_t pid;
+   char *av[5];
+   int ac = 0, bufc = 0, i;
+   char buf[2][MAXPGPATH];
+
+   if (!write_backend_variables(port))
+       return -1; /* log made by write_backend_variables */
+
+   av[ac++] = "postgres";
+   av[ac++] = "-forkexec";
+
+   /* Format up context to pass to exec'd process */
+   snprintf(buf[bufc++],MAXPGPATH,"%lu",tmpBackendFileNum);
+   /* FIXME: [fork/exec] whitespaces in directories? */
+   snprintf(buf[bufc++],MAXPGPATH,"%s",DataDir);
+
+   /* Add to the arg list */
+   Assert(bufc <= lengthof(buf));
+   for (i = 0; i < bufc; i++)
+       av[ac++] = buf[i];
+
+   /* FIXME: [fork/exec] ExtraOptions? */
+
+   av[ac++] = NULL;
+   Assert(ac <= lengthof(av));
+
+   /* Fire off execv in child */
+   if ((pid = fork()) == 0 && (execv(pg_pathname,av) == -1))
+       /*
+        * FIXME: [fork/exec] suggestions for what to do here?
+        *  Probably OK to issue error (unlike pgstat case)
+        */
+       abort();
+
+   return pid; /* Parent returns pid */
+}
+
+#endif
+
+
 /*
  * ExitPostmaster -- cleanup
  *
@@ -2851,6 +2917,9 @@ CountChildren(void)
  *
  * Return value of SSDataBase is subprocess' PID, or 0 if failed to start subprocess
  * (0 is returned only for checkpoint case).
+ *
+ * note: in the EXEC_BACKEND case, we delay the fork until argument list has been
+ * established
  */
 NON_EXEC_STATIC void
 SSDataBaseInit(int xlop)
@@ -2894,16 +2963,20 @@ SSDataBase(int xlop)
 {
    pid_t       pid;
    Backend    *bn;
-
+#ifndef EXEC_BACKEND
 #ifdef LINUX_PROFILE
    struct itimerval prof_itimer;
 #endif
+#else
+   char        idbuf[32];
+#endif
 
    fflush(stdout);
    fflush(stderr);
 
+#ifndef EXEC_BACKEND
 #ifdef LINUX_PROFILE
-   /* see comments in BackendStartup */
+   /* see comments in BackendRun */
    getitimer(ITIMER_PROF, &prof_itimer);
 #endif
 
@@ -2912,13 +2985,16 @@ SSDataBase(int xlop)
    beos_before_backend_startup();
 #endif
 
+   /* Non EXEC_BACKEND case; fork here */
    if ((pid = fork()) == 0)    /* child */
+#endif
    {
        char       *av[10];
        int         ac = 0;
        char        nbbuf[32];
        char        xlbuf[32];
 
+#ifndef EXEC_BACKEND
 #ifdef LINUX_PROFILE
        setitimer(ITIMER_PROF, &prof_itimer, NULL);
 #endif
@@ -2931,8 +3007,10 @@ SSDataBase(int xlop)
        /* Close the postmaster's sockets */
        ClosePostmasterPorts(true);
 
-#ifndef EXEC_BACKEND
        SSDataBaseInit(xlop);
+#else
+       if (!write_backend_variables(NULL))
+           return -1; /* log issued by write_backend_variables */
 #endif
 
        /* Set up command-line arguments for subprocess */
@@ -2941,7 +3019,6 @@ SSDataBase(int xlop)
 #ifdef EXEC_BACKEND
        av[ac++] = "-boot";
 #endif
-
        snprintf(nbbuf, sizeof(nbbuf), "-B%d", NBuffers);
        av[ac++] = nbbuf;
 
@@ -2949,22 +3026,30 @@ SSDataBase(int xlop)
        av[ac++] = xlbuf;
 
 #ifdef EXEC_BACKEND
-       write_backend_variables(getpid(),NULL);
-
        /* pass data dir before end of secure switches (-p) */
        av[ac++] = "-D";
        av[ac++] = DataDir;
-#endif
+
+       /* and the backend identifier + dbname */
+       snprintf(idbuf, sizeof(idbuf), "-p%lu,template1", tmpBackendFileNum);
+       av[ac++] = idbuf;
+#else
        av[ac++] = "-p";
        av[ac++] = "template1";
+#endif
 
        av[ac] = (char *) NULL;
 
        Assert(ac < lengthof(av));
 
 #ifdef EXEC_BACKEND
-       if (execv(pg_pathname,av) == -1)
-           elog(FATAL,"unable to execv in SSDataBase: %m");
+       /* EXEC_BACKEND case; fork/exec here */
+       if ((pid = fork()) == 0 && (execv(pg_pathname,av) == -1))
+       {
+           /* in child */
+           elog(ERROR,"unable to execv in SSDataBase: %m");
+           exit(0);
+       }
 #else
        BootstrapMain(ac, av);
        ExitPostmaster(0);
@@ -2974,11 +3059,12 @@ SSDataBase(int xlop)
    /* in parent */
    if (pid < 0)
    {
+#ifndef EXEC_BACKEND
 #ifdef __BEOS__
        /* Specific beos actions before backend startup */
        beos_backend_startup_failed();
 #endif
-
+#endif
        switch (xlop)
        {
            case BS_XLOG_STARTUP:
@@ -3111,6 +3197,7 @@ postmaster_error(const char *fmt,...)
  * The following need to be available to the read/write_backend_variables
  * functions
  */
+#include "storage/spin.h"
 extern XLogRecPtr RedoRecPtr;
 extern XLogwrtResult LogwrtResult;
 extern slock_t *ShmemLock;
@@ -3124,22 +3211,22 @@ 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)
+       do {                                \
+           Assert(DataDir);                \
+           sprintf((buf),                  \
+               "%s/%s/%s.backend_var.%lu", \
+               DataDir,                    \
+               PG_TEMP_FILES_DIR,          \
+               PG_TEMP_FILE_PREFIX,        \
+               (id));                      \
+       } while (0)
 
-static void
-write_backend_variables(pid_t pid, Port *port)
+static bool
+write_backend_variables(Port *port)
 {
    char    filename[MAXPGPATH];
    FILE    *fp;
-   get_tmp_backend_file_name(filename,pid);
+   get_tmp_backend_file_name(filename,++tmpBackendFileNum);
 
    /* Open file */
    fp = AllocateFile(filename, PG_BINARY_W);
@@ -3156,7 +3243,7 @@ write_backend_variables(pid_t pid, Port *port)
            ereport(ERROR,
                (errcode_for_file_access(),
                errmsg("could not write to file \"%s\": %m", filename)));
-           return;
+           return false;
        }
    }
 
@@ -3188,16 +3275,20 @@ write_backend_variables(pid_t pid, Port *port)
    write_var(ProcStructLock,fp);
    write_var(pgStatSock,fp);
 
+   write_var(PreAuthDelay,fp);
+   write_var(debug_flag,fp);
+
    /* Release file */
    FreeFile(fp);
+   return true;
 }
 
 void
-read_backend_variables(pid_t pid, Port *port)
+read_backend_variables(unsigned long id, Port *port)
 {
    char    filename[MAXPGPATH];
    FILE    *fp;
-   get_tmp_backend_file_name(filename,pid);
+   get_tmp_backend_file_name(filename,id);
 
    /* Open file */
    fp = AllocateFile(filename, PG_BINARY_R);
@@ -3237,6 +3328,9 @@ read_backend_variables(pid_t pid, Port *port)
    read_var(ProcStructLock,fp);
    read_var(pgStatSock,fp);
 
+   read_var(PreAuthDelay,fp);
+   read_var(debug_flag,fp);
+
    /* Release file */
    FreeFile(fp);
    if (unlink(filename) != 0)
index 6d32675674abb642972318cd4df8f3dfef17c48d..b99d6b4fe6ffdcebc0d770ff1c919320822380a5 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.382 2004/01/06 17:36:31 neilc Exp $
+ *   $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.383 2004/01/06 23:15:22 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
  * ----------------
@@ -2063,7 +2058,7 @@ PostgresMain(int argc, char *argv[], const char *username)
     *
     * If we are running under the postmaster, this is done already.
     */
-   if (!IsUnderPostmaster || ExecBackend)
+   if (!IsUnderPostmaster)
        MemoryContextInit();
 
    set_ps_display("startup");
@@ -2268,11 +2263,7 @@ PostgresMain(int argc, char *argv[], const char *username)
                 */
                if (secure)
                {
-#ifdef EXEC_BACKEND
-                   IsUnderPostmaster = true;
-#else
                    dbname = strdup(optarg);
-#endif
 
                    secure = false;     /* subsequent switches are NOT
                                         * secure */
@@ -2478,25 +2469,7 @@ 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
        ProcessConfigFile(PGC_POSTMASTER);
index 86fb2e03f4ae42ce8e060912f6f71a0fd9bb7c28..e502a154bbfa98aa4c84208355082b77b0f79b75 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/miscadmin.h,v 1.141 2004/01/06 17:36:31 neilc Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.142 2004/01/06 23:15:22 momjian Exp $
  *
  * NOTES
  *   some of the information in this file should be moved to
@@ -115,6 +115,9 @@ extern bool ClientAuthInProgress;
 extern const bool ExecBackend;
 
 extern int PostmasterMain(int argc, char *argv[]);
+#ifdef EXEC_BACKEND
+extern void SubPostmasterMain(int argc, char* argv[]);
+#endif
 extern void ClosePostmasterPorts(bool pgstat_too);
 
 /*