Index: src/backend/bootstrap/bootstrap.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/bootstrap/bootstrap.c,v retrieving revision 1.172 diff -c -r1.172 bootstrap.c *** src/backend/bootstrap/bootstrap.c 25 Dec 2003 03:52:50 -0000 1.172 --- src/backend/bootstrap/bootstrap.c 28 Dec 2003 10:26:41 -0000 *************** *** 51,57 **** #ifdef EXEC_BACKEND typedef struct Port Port; extern void SSDataBaseInit(int); ! extern void read_backend_variables(pid_t, Port*); #endif extern int Int_yyparse(void); --- 51,57 ---- #ifdef EXEC_BACKEND typedef struct Port Port; extern void SSDataBaseInit(int); ! extern void read_backend_variables(unsigned long, Port*); #endif extern int Int_yyparse(void); *************** *** 231,236 **** --- 231,239 ---- int flag; int xlogop = BS_XLOG_NOP; char *potential_DataDir = NULL; + #ifdef EXEC_BACKEND + unsigned long backendID = 0; + #endif /* * initialize globals *************** *** 291,300 **** break; case 'p': #ifdef EXEC_BACKEND ! IsUnderPostmaster = true; #endif dbname = strdup(optarg); ! break; case 'B': SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV); break; --- 294,308 ---- break; case 'p': #ifdef EXEC_BACKEND ! { ! char buf[MAXPGPATH]; ! IsUnderPostmaster = true; ! sscanf(optarg,"%lu,%s",&backendID,buf); ! dbname = strdup(buf); ! } #endif dbname = strdup(optarg); ! break; case 'B': SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV); break; *************** *** 363,369 **** { #ifdef EXEC_BACKEND read_nondefault_variables(); ! read_backend_variables(getpid(),NULL); SSDataBaseInit(xlogop); #endif --- 371,377 ---- { #ifdef EXEC_BACKEND read_nondefault_variables(); ! read_backend_variables(backendID,NULL); SSDataBaseInit(xlogop); #endif *************** *** 431,441 **** switch (xlogop) { case BS_XLOG_BGWRITER: ! InitDummyProcess(DUMMY_PROC_BGWRITER); break; ! default: ! InitDummyProcess(DUMMY_PROC_DEFAULT); break; } } --- 439,449 ---- switch (xlogop) { case BS_XLOG_BGWRITER: ! InitDummyProcess(DUMMY_PROC_BGWRITER); break; ! default: ! InitDummyProcess(DUMMY_PROC_DEFAULT); break; } } Index: src/backend/main/main.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/main/main.c,v retrieving revision 1.69 diff -c -r1.69 main.c *** src/backend/main/main.c 25 Dec 2003 03:52:50 -0000 1.69 --- src/backend/main/main.c 28 Dec 2003 10:26:41 -0000 *************** *** 203,211 **** /* * 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. */ len = strlen(new_argv[0]); --- 203,211 ---- /* * Now dispatch to one of PostmasterMain, PostgresMain, GucInfoMain, ! * SubPostmasterMain, pgstat_main, pgstat_mainChild or BootstrapMain ! * depending on the program name (and possibly first argument) we ! * were called with. The lack of consistency here is historical. */ len = strlen(new_argv[0]); *************** *** 223,228 **** --- 223,238 ---- 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: src/backend/postmaster/pgstat.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/pgstat.c,v retrieving revision 1.50 diff -c -r1.50 pgstat.c *** src/backend/postmaster/pgstat.c 25 Dec 2003 03:52:51 -0000 1.50 --- src/backend/postmaster/pgstat.c 28 Dec 2003 10:26:43 -0000 *************** *** 107,113 **** * ---------- */ #ifdef EXEC_BACKEND ! static void pgstat_exec(STATS_PROCESS_TYPE procType); static void pgstat_parseArgs(PGSTAT_FORK_ARGS); #endif NON_EXEC_STATIC void pgstat_main(PGSTAT_FORK_ARGS); --- 107,113 ---- * ---------- */ #ifdef EXEC_BACKEND ! 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,351 **** #ifdef EXEC_BACKEND /* ---------- ! * pgstat_exec() - * ! * Used to format up the arglist for, and exec, statistics * (buffer and collector) processes * */ ! static void ! pgstat_exec(STATS_PROCESS_TYPE procType) { char *av[11]; int ac = 0, bufc = 0, i; char pgstatBuf[8][MAXPGPATH]; --- 337,352 ---- #ifdef EXEC_BACKEND /* ---------- ! * pgstat_forkexec() - * ! * Used to format up the arglist for, then fork and exec, statistics * (buffer and collector) processes * */ ! static pid_t ! pgstat_forkexec(STATS_PROCESS_TYPE procType) { + pid_t pid; char *av[11]; int ac = 0, bufc = 0, i; char pgstatBuf[8][MAXPGPATH]; *************** *** 387,395 **** av[ac++] = NULL; Assert(ac <= lengthof(av)); ! if (execv(pg_pathname,av) == -1) /* FIXME: [fork/exec] suggestions for what to do here? Can't call elog... */ ! Assert(false); } --- 388,399 ---- 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? Can't call elog... */ ! abort(); ! ! return pid; /* Parent returns pid */ } *************** *** 479,485 **** --- 483,493 ---- 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,521 **** (errmsg("could not fork statistics buffer: %m"))); return; case 0: break; 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 } --- 498,524 ---- (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; } } *************** *** 1385,1412 **** exit(1); } switch (fork()) { case -1: ereport(LOG, (errmsg("could not fork statistics collector: %m"))); exit(1); case 0: /* child becomes collector process */ - #ifdef EXEC_BACKEND - pgstat_exec(STAT_PROC_COLLECTOR); - #else pgstat_mainChild(); #endif - exit(0); default: /* parent becomes buffer process */ closesocket(pgStatPipe[0]); pgstat_recvbuffer(); - exit(0); } } --- 1388,1418 ---- 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 */ pgstat_mainChild(); + break; #endif default: /* parent becomes buffer process */ closesocket(pgStatPipe[0]); pgstat_recvbuffer(); } + exit(0); } Index: src/backend/postmaster/postmaster.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v retrieving revision 1.353 diff -c -r1.353 postmaster.c *** src/backend/postmaster/postmaster.c 25 Dec 2003 03:52:51 -0000 1.353 --- src/backend/postmaster/postmaster.c 28 Dec 2003 10:26:46 -0000 *************** *** 273,280 **** 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 *); static int ServerLoop(void); --- 273,280 ---- static void CleanupProc(int pid, int exitstatus); static void LogChildExit(int lev, const char *procname, int pid, int exitstatus); ! 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,304 **** __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); #endif #define StartupDataBase() SSDataBase(BS_XLOG_STARTUP) --- 297,307 ---- __attribute__((format(printf, 1, 2))); #ifdef EXEC_BACKEND ! 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,922 **** #endif #ifdef LINUX_PROFILE ! /* see comments in BackendStartup */ getitimer(ITIMER_PROF, &prof_itimer); #endif --- 919,925 ---- #endif #ifdef LINUX_PROFILE ! /* see comments in BackendRun */ getitimer(ITIMER_PROF, &prof_itimer); #endif *************** *** 1310,1316 **** * 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 * worry about leaking this storage on failure, since we aren't in the * postmaster process anymore. */ --- 1313,1319 ---- * 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 BackendRun). We need not * worry about leaking this storage on failure, since we aren't in the * postmaster process anymore. */ *************** *** 2235,2246 **** beos_before_backend_startup(); #endif pid = fork(); if (pid == 0) /* child */ { - int status; - #ifdef LINUX_PROFILE setitimer(ITIMER_PROF, &prof_itimer, NULL); #endif --- 2238,2251 ---- beos_before_backend_startup(); #endif + port->canAcceptConnections = canAcceptConnections(); + #ifdef EXEC_BACKEND + pid = Backend_forkexec(port); + #else pid = fork(); if (pid == 0) /* child */ { #ifdef LINUX_PROFILE setitimer(ITIMER_PROF, &prof_itimer, NULL); #endif *************** *** 2251,2263 **** #endif free(bn); ! status = BackendFork(port); ! ! if (status != 0) ! ereport(LOG, ! (errmsg("connection startup failed"))); ! proc_exit(status); } /* in parent, error */ if (pid < 0) --- 2256,2264 ---- #endif free(bn); ! proc_exit(BackendRun(port)); } + #endif /* in parent, error */ if (pid < 0) *************** *** 2349,2363 **** /* ! * 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. */ ! NON_EXEC_STATIC bool BackendInit(Port *port) { int status; --- 2350,2364 ---- /* ! * 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. */ ! static void BackendInit(Port *port) { int status; *************** *** 2447,2453 **** status = ProcessStartupPacket(port, false); if (status != STATUS_OK) ! return false; /* cancel request processed, or error */ /* * Now that we have the user and database name, we can set the process --- 2448,2458 ---- status = ProcessStartupPacket(port, false); if (status != STATUS_OK) ! { ! ereport(LOG, ! (errmsg("connection startup failed"))); ! proc_exit(status); ! } /* * Now that we have the user and database name, we can set the process *************** *** 2483,2509 **** 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) { 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 --- 2488,2505 ---- random_seed = 0; gettimeofday(&now, &tz); srandom((unsigned int) now.tv_usec); } static int ! BackendRun(Port *port) { char **av; int maxac; int ac; char debugbuf[32]; char protobuf[32]; int i; /* * Let's clean up ourselves as the postmaster child, and *************** *** 2521,2532 **** 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. --- 2517,2525 ---- if (PreAuthDelay > 0) sleep(PreAuthDelay); ! /* Will exit on failure */ ! BackendInit(port); /* ---------------- * Now, build the argv vector that will be given to PostgresMain. *************** *** 2563,2610 **** /* * 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); - #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; /* ! * 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 /* * 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); --- 2556,2585 ---- /* * Pass any backend switches specified with -o in the postmaster's own * command line. We assume these are secure. */ ! split_opts(av, &ac, ExtraOptions); /* Tell the backend what protocol the frontend is using. */ snprintf(protobuf, sizeof(protobuf), "-v%u", port->proto); av[ac++] = protobuf; #ifdef EXEC_BACKEND /* pass data dir before end of secure switches (-p) */ av[ac++] = "-D"; av[ac++] = DataDir; + #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"; av[ac++] = port->database_name; /* * Pass the (insecure) option switches from the connection request. * (It's OK to mangle port->cmdline_options now.) */ if (port->cmdline_options) split_opts(av, &ac, port->cmdline_options); *************** *** 2620,2626 **** --- 2595,2603 ---- * username isn't lost either; see ProcessStartupPacket(). */ MemoryContextSwitchTo(TopMemoryContext); + #ifndef EXEC_BACKEND MemoryContextDelete(PostmasterContext); + #endif PostmasterContext = NULL; /* *************** *** 2635,2650 **** 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 } /* * ExitPostmaster -- cleanup * --- 2612,2716 ---- ereport(DEBUG3, (errmsg_internal(")"))); ClientAuthInProgress = false; /* client_min_messages is active * now */ return (PostgresMain(ac, av, port->user_name)); } + + #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,2856 **** --- 2917,2925 ---- * * 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,2909 **** { pid_t pid; Backend *bn; ! #ifdef LINUX_PROFILE struct itimerval prof_itimer; #endif fflush(stdout); fflush(stderr); #ifdef LINUX_PROFILE ! /* see comments in BackendStartup */ getitimer(ITIMER_PROF, &prof_itimer); #endif --- 2963,2982 ---- { 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 BackendRun */ getitimer(ITIMER_PROF, &prof_itimer); #endif *************** *** 2912,2924 **** --- 2985,3000 ---- 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,2938 **** /* Close the postmaster's sockets */ ClosePostmasterPorts(true); - #ifndef EXEC_BACKEND SSDataBaseInit(xlop); #endif /* Set up command-line arguments for subprocess */ --- 3007,3016 ---- /* Close the postmaster's sockets */ ClosePostmasterPorts(true); 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,2947 **** #ifdef EXEC_BACKEND av[ac++] = "-boot"; #endif - snprintf(nbbuf, sizeof(nbbuf), "-B%d", NBuffers); av[ac++] = nbbuf; --- 3019,3024 ---- *************** *** 2949,2970 **** 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 av[ac++] = "-p"; av[ac++] = "template1"; 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"); #else BootstrapMain(ac, av); ExitPostmaster(0); --- 3026,3055 ---- av[ac++] = xlbuf; #ifdef EXEC_BACKEND /* pass data dir before end of secure switches (-p) */ av[ac++] = "-D"; av[ac++] = DataDir; ! ! /* 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 ! /* 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,2984 **** /* in parent */ if (pid < 0) { #ifdef __BEOS__ /* Specific beos actions before backend startup */ beos_backend_startup_failed(); #endif ! switch (xlop) { case BS_XLOG_STARTUP: --- 3059,3070 ---- /* 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,3116 **** --- 3197,3203 ---- * 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,3145 **** #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); --- 3211,3232 ---- #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.%lu", \ ! DataDir, \ ! PG_TEMP_FILES_DIR, \ ! PG_TEMP_FILE_PREFIX, \ ! (id)); \ ! } while (0) ! static bool ! write_backend_variables(Port *port) { char filename[MAXPGPATH]; FILE *fp; ! get_tmp_backend_file_name(filename,++tmpBackendFileNum); /* Open file */ fp = AllocateFile(filename, PG_BINARY_W); *************** *** 3156,3162 **** ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", filename))); ! return; } } --- 3243,3249 ---- ereport(ERROR, (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", filename))); ! return false; } } *************** *** 3188,3203 **** 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); --- 3275,3294 ---- 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(unsigned long id, Port *port) { char filename[MAXPGPATH]; FILE *fp; ! get_tmp_backend_file_name(filename,id); /* Open file */ fp = AllocateFile(filename, PG_BINARY_R); *************** *** 3236,3241 **** --- 3327,3335 ---- read_var(LWLockArray,fp); read_var(ProcStructLock,fp); read_var(pgStatSock,fp); + + read_var(PreAuthDelay,fp); + read_var(debug_flag,fp); /* Release file */ FreeFile(fp); Index: src/backend/tcop/postgres.c =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/backend/tcop/postgres.c,v retrieving revision 1.381 diff -c -r1.381 postgres.c *** src/backend/tcop/postgres.c 25 Dec 2003 03:52:51 -0000 1.381 --- src/backend/tcop/postgres.c 28 Dec 2003 10:26:52 -0000 *************** *** 68,78 **** extern int optind; extern char *optarg; - #ifdef EXEC_BACKEND - extern bool BackendInit(Port*); - extern void read_backend_variables(pid_t, Port*); - #endif - /* ---------------- * global variables * ---------------- --- 68,73 ---- *************** *** 2063,2069 **** * * If we are running under the postmaster, this is done already. */ ! if (!IsUnderPostmaster || ExecBackend) MemoryContextInit(); set_ps_display("startup"); --- 2058,2064 ---- * * If we are running under the postmaster, this is done already. */ ! if (!IsUnderPostmaster) MemoryContextInit(); set_ps_display("startup"); *************** *** 2277,2287 **** */ if (secure) { - #ifdef EXEC_BACKEND - IsUnderPostmaster = true; - #else dbname = strdup(optarg); - #endif secure = false; /* subsequent switches are NOT * secure */ --- 2272,2278 ---- *************** *** 2487,2511 **** 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); --- 2478,2484 ---- Index: src/include/miscadmin.h =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/include/miscadmin.h,v retrieving revision 1.140 diff -c -r1.140 miscadmin.h *** src/include/miscadmin.h 21 Dec 2003 04:34:35 -0000 1.140 --- src/include/miscadmin.h 28 Dec 2003 10:26:52 -0000 *************** *** 115,120 **** --- 115,123 ---- 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); /*