diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index d33c683a4ee83001714afede9ebb304ae0455489..57a1c99d61cf6031122fc49d7e3d6846152ba1b1 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -14,7 +14,6 @@ */ #include "postgres.h" -#include <time.h> #include <unistd.h> #include <signal.h> @@ -191,19 +190,11 @@ AuxiliaryProcessMain(int argc, char *argv[]) char *userDoption = NULL; /* - * initialize globals + * Initialize process environment (already done if under postmaster, but + * not if standalone). */ - MyProcPid = getpid(); - - MyStartTime = time(NULL); - - /* Compute paths, if we didn't inherit them from postmaster */ - if (my_exec_path[0] == '\0') - { - if (find_my_exec(progname, my_exec_path) < 0) - elog(FATAL, "%s: could not locate my own executable path", - progname); - } + if (!IsUnderPostmaster) + InitStandaloneProcess(argv[0]); /* * process command arguments @@ -515,15 +506,6 @@ bootstrap_signals(void) { if (IsUnderPostmaster) { - /* - * If possible, make this process a group leader, so that the - * postmaster can signal any child processes too. - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Properly accept or ignore signals the postmaster might send us */ diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c index 062b1209051f53ebae70b58eea3c6c5b2e494828..a26eee25d46405515ea7944b2ce95290893969b1 100644 --- a/src/backend/postmaster/autovacuum.c +++ b/src/backend/postmaster/autovacuum.c @@ -64,7 +64,6 @@ #include <signal.h> #include <sys/types.h> #include <sys/time.h> -#include <time.h> #include <unistd.h> #include "access/heapam.h" @@ -383,12 +382,11 @@ StartAutoVacLauncher(void) #ifndef EXEC_BACKEND case 0: /* in postmaster child ... */ + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(false); - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - AutoVacLauncherMain(0, NULL); break; #endif @@ -408,16 +406,8 @@ AutoVacLauncherMain(int argc, char *argv[]) { sigjmp_buf local_sigjmp_buf; - /* we are a postmaster subprocess now */ - IsUnderPostmaster = true; am_autovacuum_launcher = true; - /* reset MyProcPid */ - MyProcPid = getpid(); - - /* record Start Time for logging */ - MyStartTime = time(NULL); - /* Identify myself via ps */ init_ps_display("autovacuum launcher process", "", "", ""); @@ -429,17 +419,6 @@ AutoVacLauncherMain(int argc, char *argv[]) SetProcessingMode(InitProcessing); - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (autovacuum probably never has any - * child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Set up signal handlers. We operate on databases much like a regular * backend, so we use the same signal handling. See equivalent code in @@ -1455,12 +1434,11 @@ StartAutoVacWorker(void) #ifndef EXEC_BACKEND case 0: /* in postmaster child ... */ + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(false); - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - AutoVacWorkerMain(0, NULL); break; #endif @@ -1481,32 +1459,13 @@ AutoVacWorkerMain(int argc, char *argv[]) sigjmp_buf local_sigjmp_buf; Oid dbid; - /* we are a postmaster subprocess now */ - IsUnderPostmaster = true; am_autovacuum_worker = true; - /* reset MyProcPid */ - MyProcPid = getpid(); - - /* record Start Time for logging */ - MyStartTime = time(NULL); - /* Identify myself via ps */ init_ps_display("autovacuum worker process", "", "", ""); SetProcessingMode(InitProcessing); - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (autovacuum probably never has any - * child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Set up signal handlers. We operate on databases much like a regular * backend, so we use the same signal handling. See equivalent code in diff --git a/src/backend/postmaster/bgworker.c b/src/backend/postmaster/bgworker.c index 8a7637baec96cb81109880ab35a5ea5026ae6a8b..6673f5ba622d1d71fb6aefe765351a49bf48a92b 100644 --- a/src/backend/postmaster/bgworker.c +++ b/src/backend/postmaster/bgworker.c @@ -13,7 +13,6 @@ #include "postgres.h" #include <unistd.h> -#include <time.h> #include "miscadmin.h" #include "libpq/pqsignal.h" @@ -556,16 +555,8 @@ StartBackgroundWorker(void) if (worker == NULL) elog(FATAL, "unable to find bgworker entry"); - /* we are a postmaster subprocess now */ - IsUnderPostmaster = true; IsBackgroundWorker = true; - /* reset MyProcPid */ - MyProcPid = getpid(); - - /* record Start Time for logging */ - MyStartTime = time(NULL); - /* Identify myself via ps */ snprintf(buf, MAXPGPATH, "bgworker: %s", worker->bgw_name); init_ps_display(buf, "", "", ""); @@ -590,15 +581,6 @@ StartBackgroundWorker(void) if (PostAuthDelay > 0) pg_usleep(PostAuthDelay * 1000000L); - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Set up signal handlers. */ diff --git a/src/backend/postmaster/bgwriter.c b/src/backend/postmaster/bgwriter.c index 872c23110aeb977b7c63019190290fd8e13cd747..f138eb7473bf89ecde321b134f95f59b25b0bf3f 100644 --- a/src/backend/postmaster/bgwriter.c +++ b/src/backend/postmaster/bgwriter.c @@ -36,7 +36,6 @@ #include <signal.h> #include <sys/time.h> -#include <time.h> #include <unistd.h> #include "access/xlog.h" @@ -113,17 +112,6 @@ BackgroundWriterMain(void) MemoryContext bgwriter_context; bool prev_hibernate; - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (bgwriter probably never has any - * child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Properly accept or ignore signals the postmaster might send us. * diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 4d1ba40ec8804fb4c41182dd88d38bc0782ed482..3c9c216c6f1050741337aa2e65ed1f3be4aaac46 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -196,17 +196,6 @@ CheckpointerMain(void) CheckpointerShmem->checkpointer_pid = MyProcPid; - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (checkpointer probably never has - * any child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Properly accept or ignore signals the postmaster might send us * diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c index 75e7e1b2903e496b72dcec849eb4048cecd676f3..78dec3a4c6fce00700edee45d9311b58fb4c6027 100644 --- a/src/backend/postmaster/pgarch.c +++ b/src/backend/postmaster/pgarch.c @@ -157,12 +157,11 @@ pgarch_start(void) #ifndef EXEC_BACKEND case 0: /* in postmaster child ... */ + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(false); - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - /* Drop our connection to postmaster's shared memory, as well */ dsm_detach_all(); PGSharedMemoryDetach(); @@ -221,21 +220,6 @@ pgarch_forkexec(void) NON_EXEC_STATIC void PgArchiverMain(int argc, char *argv[]) { - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); /* record Start Time for logging */ - - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - InitializeLatchSupport(); /* needed for latch waits */ InitLatch(&mainloop_latch); /* initialize latch used in main loop */ diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c index ea3bd4b3e8898fff70944fbb2455a3a3260d0a0f..fa87660baeeba00ecf0c3d734c077cbe24a94d6b 100644 --- a/src/backend/postmaster/pgstat.c +++ b/src/backend/postmaster/pgstat.c @@ -695,12 +695,11 @@ pgstat_start(void) #ifndef EXEC_BACKEND case 0: /* in postmaster child ... */ + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(false); - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - /* Drop our connection to postmaster's shared memory, as well */ dsm_detach_all(); PGSharedMemoryDetach(); @@ -3152,23 +3151,6 @@ PgstatCollectorMain(int argc, char *argv[]) PgStat_Msg msg; int wr; - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); /* record Start Time for logging */ - - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (pgstat probably never has any - * child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - InitializeLatchSupport(); /* needed for latch waits */ /* Initialize private latch for use by signal handlers */ diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index 8570e75d8a6f9ce7b25cb17396b6f9dacf223880..fe6316ecbe928143a09b28e51c5930af91d70c60 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -3811,19 +3811,8 @@ BackendStartup(Port *port) { free(bn); - /* - * Let's clean up ourselves as the postmaster child, and close the - * postmaster's listen sockets. (In EXEC_BACKEND case this is all - * done in SubPostmasterMain.) - */ - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); - - /* We don't want the postmaster's proc_exit() handlers */ - on_exit_reset(); + /* Detangle from postmaster */ + InitPostmasterChild(); /* Close the postmaster's sockets */ ClosePostmasterPorts(false); @@ -3953,16 +3942,6 @@ BackendInitialize(Port *port) pq_init(); /* initialize libpq to talk to client */ whereToSendOutput = DestRemote; /* now safe to ereport to client */ - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (We do this now on the off chance - * that something might spawn a child process during authentication.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * We arrange for a simple exit(1) if we receive SIGTERM or SIGQUIT or * timeout while trying to collect the startup packet. Otherwise the @@ -4515,30 +4494,13 @@ SubPostmasterMain(int argc, char *argv[]) { Port port; - /* Do this sooner rather than later... */ - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); - - /* - * make sure stderr is in binary mode before anything can possibly be - * written to it, in case it's actually the syslogger pipe, so the pipe - * chunking protocol isn't disturbed. Non-logpipe data gets translated on - * redirection (e.g. via pg_ctl -l) anyway. - */ -#ifdef WIN32 - _setmode(fileno(stderr), _O_BINARY); -#endif - - /* Lose the postmaster's on-exit routines (really a no-op) */ - on_exit_reset(); - /* In EXEC_BACKEND case we will not have inherited these settings */ IsPostmasterEnvironment = true; whereToSendOutput = DestNone; + /* Setup as postmaster child */ + InitPostmasterChild(); + /* Setup essential subsystems (to ensure elog() behaves sanely) */ InitializeGUCOptions(); @@ -4718,6 +4680,8 @@ SubPostmasterMain(int argc, char *argv[]) /* do this as early as possible; in particular, before InitProcess() */ IsBackgroundWorker = true; + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(false); @@ -5138,14 +5102,11 @@ StartChildProcess(AuxProcType type) if (pid == 0) /* child */ { - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ + InitPostmasterChild(); /* Close the postmaster's sockets */ ClosePostmasterPorts(false); - /* Lose the postmaster's on-exit routines and port connections */ - on_exit_reset(); - /* Release postmaster's working memory context */ MemoryContextSwitchTo(TopMemoryContext); MemoryContextDelete(PostmasterContext); @@ -5424,12 +5385,11 @@ do_start_bgworker(RegisteredBgWorker *rw) #ifndef EXEC_BACKEND case 0: /* in postmaster child ... */ + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(false); - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - /* Do NOT release postmaster's working memory context */ MyBgworkerEntry = &rw->rw_worker; diff --git a/src/backend/postmaster/startup.c b/src/backend/postmaster/startup.c index 72501e07f31a6ca51c4c5afdc69ae4ddadd29e05..581837a156740fb11e6902a010e23ccdfcf035cc 100644 --- a/src/backend/postmaster/startup.c +++ b/src/backend/postmaster/startup.c @@ -177,15 +177,6 @@ HandleStartupProcInterrupts(void) void StartupProcessMain(void) { - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Properly accept or ignore signals the postmaster might send us. */ diff --git a/src/backend/postmaster/syslogger.c b/src/backend/postmaster/syslogger.c index c1b64ac751300300963e359fb4e44add76f8d6e9..d127fb577118836ab4004760ebe049f36957ee2b 100644 --- a/src/backend/postmaster/syslogger.c +++ b/src/backend/postmaster/syslogger.c @@ -164,11 +164,6 @@ SysLoggerMain(int argc, char *argv[]) int currentLogRotationAge; pg_time_t now; - IsUnderPostmaster = true; /* we are a postmaster subprocess now */ - - MyProcPid = getpid(); /* reset MyProcPid */ - - MyStartTime = time(NULL); /* set our start time in case we call elog */ now = MyStartTime; #ifdef EXEC_BACKEND @@ -236,18 +231,8 @@ SysLoggerMain(int argc, char *argv[]) syslogPipe[1] = 0; #endif - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (syslogger probably never has any - * child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif + InitializeLatchSupport(); /* needed for latch waits */ - InitializeLatchSupport(); /* needed for latch waits */ /* Initialize private latch for use by signal handlers */ InitLatch(&sysLoggerLatch); @@ -609,12 +594,11 @@ SysLogger_Start(void) #ifndef EXEC_BACKEND case 0: /* in postmaster child ... */ + InitPostmasterChild(); + /* Close the postmaster's sockets */ ClosePostmasterPorts(true); - /* Lose the postmaster's on-exit routines */ - on_exit_reset(); - /* Drop our connection to postmaster's shared memory, as well */ dsm_detach_all(); PGSharedMemoryDetach(); diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c index 2101b45c1a38042d7ae2e4655ffdad33683e178b..044c30665e76a30d8bed317a6bfb3890a8b3a0c1 100644 --- a/src/backend/postmaster/walwriter.c +++ b/src/backend/postmaster/walwriter.c @@ -42,8 +42,6 @@ #include "postgres.h" #include <signal.h> -#include <sys/time.h> -#include <time.h> #include <unistd.h> #include "access/xlog.h" @@ -101,17 +99,6 @@ WalWriterMain(void) int left_till_hibernate; bool hibernating; - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (walwriter probably never has any - * child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* * Properly accept or ignore signals the postmaster might send us * diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 3dbefc603b0cf7edda4d5d4ad23f73de4f40c43b..bfbc02f02ac88704fa1fb9c2625c0a2d0c35277c 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -256,17 +256,6 @@ WalReceiverMain(void) OwnLatch(&walrcv->latch); - /* - * If possible, make this process a group leader, so that the postmaster - * can signal any child processes too. (walreceiver probably never has - * any child processes, but for consistency we make all postmaster child - * processes do this.) - */ -#ifdef HAVE_SETSID - if (setsid() < 0) - elog(FATAL, "setsid() failed: %m"); -#endif - /* Properly accept or ignore signals the postmaster might send us */ pqsignal(SIGHUP, WalRcvSigHupHandler); /* set flag to read config * file */ diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index c321236bbbb915c77bca8fcae5298be09897d7ed..f805368899af6eeaa8df1309d6bfa997d07ecf21 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -22,7 +22,6 @@ #include <fcntl.h> #include <limits.h> #include <signal.h> -#include <time.h> #include <unistd.h> #include <sys/socket.h> #ifdef HAVE_SYS_SELECT_H @@ -3536,30 +3535,12 @@ PostgresMain(int argc, char *argv[], sigjmp_buf local_sigjmp_buf; volatile bool send_ready_for_query = true; - /* - * Initialize globals (already done if under postmaster, but not if - * standalone). - */ + /* Initialize startup process environment if necessary. */ if (!IsUnderPostmaster) - { - MyProcPid = getpid(); - - MyStartTime = time(NULL); - } + InitStandaloneProcess(argv[0]); SetProcessingMode(InitProcessing); - /* Compute paths, if we didn't inherit them from postmaster */ - if (my_exec_path[0] == '\0') - { - if (find_my_exec(argv[0], my_exec_path) < 0) - elog(FATAL, "%s: could not locate my own executable path", - argv[0]); - } - - if (pkglib_path[0] == '\0') - get_pkglib_path(my_exec_path, pkglib_path); - /* * Set default values for command-line options. */ @@ -3589,11 +3570,6 @@ PostgresMain(int argc, char *argv[], proc_exit(1); } - /* - * You might expect to see a setsid() call here, but it's not needed, - * because if we are under a postmaster then BackendInitialize() did it. - */ - /* * Set up signal handlers and masks. * diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c index 7f386aee805b9662d72565d3e90dbf9606aab0f9..414b05e3b8c0edc0cd5112f2c2d4eadb9826d141 100644 --- a/src/backend/utils/init/miscinit.c +++ b/src/backend/utils/init/miscinit.c @@ -16,9 +16,11 @@ #include <sys/param.h> #include <signal.h> +#include <time.h> #include <sys/file.h> #include <sys/stat.h> #include <sys/time.h> +#include <sys/types.h> #include <fcntl.h> #include <unistd.h> #include <grp.h> @@ -160,6 +162,70 @@ static int SecurityRestrictionContext = 0; /* We also remember if a SET ROLE is currently active */ static bool SetRoleIsActive = false; +/* + * Initialize the basic environment for a postmaster child + * + * Should be called as early as possible after the child's startup. + */ +void +InitPostmasterChild(void) +{ + IsUnderPostmaster = true; /* we are a postmaster subprocess now */ + + MyProcPid = getpid(); /* reset MyProcPid */ + + MyStartTime = time(NULL); /* set our start time in case we call elog */ + + /* + * make sure stderr is in binary mode before anything can possibly be + * written to it, in case it's actually the syslogger pipe, so the pipe + * chunking protocol isn't disturbed. Non-logpipe data gets translated on + * redirection (e.g. via pg_ctl -l) anyway. + */ +#ifdef WIN32 + _setmode(fileno(stderr), _O_BINARY); +#endif + + /* We don't want the postmaster's proc_exit() handlers */ + on_exit_reset(); + + /* + * If possible, make this process a group leader, so that the postmaster + * can signal any child processes too. Not all processes will have + * children, but for consistency we , but for consistency we make all + * postmaster child processes do this. + */ +#ifdef HAVE_SETSID + if (setsid() < 0) + elog(FATAL, "setsid() failed: %m"); +#endif +} + +/* + * Initialize the basic environment for a standalone process. + * + * argv0 has to be suitable to find the program's executable. + */ +void +InitStandaloneProcess(const char *argv0) +{ + Assert(!IsPostmasterEnvironment); + + MyProcPid = getpid(); /* reset MyProcPid */ + + MyStartTime = time(NULL); /* set our start time in case we call elog */ + + /* Compute paths, no postmaster to inherit from */ + if (my_exec_path[0] == '\0') + { + if (find_my_exec(argv0, my_exec_path) < 0) + elog(FATAL, "%s: could not locate my own executable path", + argv0); + } + + if (pkglib_path[0] == '\0') + get_pkglib_path(my_exec_path, pkglib_path); +} /* * GetUserId - get the current effective user ID. diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index fc8bd7a91990d2abd966abdfec5fc94d08aa7929..b94a94499b7716dd22202bd4381deb9d0afe3d4f 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -277,6 +277,9 @@ extern int trace_recovery(int trace_level); extern char *DatabasePath; /* now in utils/init/miscinit.c */ +extern void InitPostmasterChild(void); +extern void InitStandaloneProcess(const char *argv0); + extern void SetDatabasePath(const char *path); extern char *GetUserNameFromId(Oid roleid);