1/*-------------------------------------------------------------------------
4 * Functions for launching backends and other postmaster child
7 * On Unix systems, a new child process is launched with fork(). It inherits
8 * all the global variables and data structures that had been initialized in
9 * the postmaster. After forking, the child process closes the file
10 * descriptors that are not needed in the child process, and sets up the
11 * mechanism to detect death of the parent postmaster process, etc. After
12 * that, it calls the right Main function depending on the kind of child
15 * In EXEC_BACKEND mode, which is used on Windows but can be enabled on other
16 * platforms for testing, the child process is launched by fork() + exec() (or
17 * CreateProcess() on Windows). It does not inherit the state from the
18 * postmaster, so it needs to re-attach to the shared memory, re-initialize
19 * global variables, reload the config file etc. to get the process to the
20 * same state as after fork() on a Unix system.
23 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
24 * Portions Copyright (c) 1994, Regents of the University of California
27 * src/backend/postmaster/launch_backend.c
29 *-------------------------------------------------------------------------
74/* Type for a socket that can be inherited to a client process */
78 SOCKET origsocket;
/* Original socket value, or PGINVALID_SOCKET
80 WSAPROTOCOL_INFO wsainfo;
83typedef int InheritableSocket;
87 * Structure contains all variables passed to exec:ed backends
100#ifdef USE_INJECTION_POINTS
101 struct InjectionPointsCtl *ActiveInjectionPoints;
125 HANDLE PostmasterHandle;
126 HANDLE initial_signal_pipe;
138 * These are only used by backend processes, but are here because passing
139 * a socket needs some special handling on Windows. 'client_sock' is an
140 * explicit argument to postmaster_child_launch, but is stored in
141 * MyClientSocket in the child process.
144 InheritableSocket inh_sock;
147 * Extra startup data, content depends on the child process.
149 size_t startup_data_len;
153#define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
155static void read_backend_variables(
char *
id,
void **startup_data,
size_t *startup_data_len);
156static void restore_backend_variables(BackendParameters *param);
158static bool save_backend_variables(BackendParameters *param,
int child_slot,
161 HANDLE childProcess, pid_t childPid,
163 const void *startup_data,
size_t startup_data_len);
165static pid_t internal_forkexec(
const char *child_kind,
int child_slot,
166 const void *startup_data,
size_t startup_data_len,
169#endif /* EXEC_BACKEND */
172 * Information needed to launch different kinds of child processes.
177 void (*main_fn) (
const void *startup_data,
size_t startup_data_len);
182#define PG_PROCTYPE(bktype, description, main_func, shmem_attach) \
183 [bktype] = {description, main_func, shmem_attach},
195 * Start a new postmaster child process.
197 * The child process will be restored to roughly the same state whether
198 * EXEC_BACKEND is used or not: it will be attached to shared memory if
199 * appropriate, and fds and other resources that we've inherited from
200 * postmaster that are not needed in a child process have been closed.
202 * 'child_slot' is the PMChildFlags array index reserved for the child
203 * process. 'startup_data' is an optional contiguous chunk of data that is
204 * passed to the child process.
208 void *startup_data,
size_t startup_data_len,
215 /* Capture time Postmaster initiates process creation for logging */
221 startup_data, startup_data_len, client_sock);
222 /* the child process will arrive in SubPostmasterMain */
223#else /* !EXEC_BACKEND */
225 if (pid == 0)
/* child */
227 /* Capture and transfer timings that may be needed for logging */
237 /* Close the postmaster's sockets */
240 /* Detangle from postmaster */
243 /* Detach shared memory if not needed. */
251 * Enter the Main function with TopMemoryContext. The startup data is
252 * allocated in PostmasterContext, so we cannot release it here yet.
253 * The Main function will do it after it's done handling the startup
266 * Run the appropriate Main function
271#endif /* EXEC_BACKEND */
279 * internal_forkexec non-win32 implementation
281 * - writes out backend variables to the parameter file
282 * - fork():s, and then exec():s the child process
285internal_forkexec(
const char *child_kind,
int child_slot,
286 const void *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
288 static unsigned long tmpBackendFileNum = 0;
292 BackendParameters *param;
298 * Use palloc0 to make sure padding bytes are initialized, to prevent
299 * Valgrind from complaining about writing uninitialized bytes to the
300 * file. This isn't performance critical, and the win32 implementation
301 * initializes the padding bytes to zeros, so do it even when not using
304 paramsz = SizeOfBackendParameters(startup_data_len);
306 if (!save_backend_variables(param, child_slot, client_sock, startup_data, startup_data_len))
309 return -1;
/* log made by save_backend_variables */
312 /* Calculate name for temp file */
322 * As in OpenTemporaryFileInTablespace, try to make the temp-file
323 * directory, ignoring errors.
332 errmsg(
"could not create file \"%s\": %m",
339 if (fwrite(param, paramsz, 1, fp) != 1)
343 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
355 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
359 /* set up argv properly */
360 argv[0] =
"postgres";
363 /* Insert temp file name after --forkchild argument */
364 argv[2] = tmpfilename;
367 /* Fire off execv in child */
370 if (execv(postgres_exec_path, argv) < 0)
373 (
errmsg(
"could not execute server process \"%s\": %m",
374 postgres_exec_path)));
375 /* We're already in the child process here, can't return */
380 return pid;
/* Parent returns pid, or -1 on fork failure */
385 * internal_forkexec win32 implementation
387 * - starts backend using CreateProcess(), in suspended state
388 * - writes out backend variables to the parameter file
389 * - during this, duplicates handles and sockets required for
390 * inheritance into the new process
391 * - resumes execution of the new process once the backend parameter
395internal_forkexec(
const char *child_kind,
int child_slot,
396 const void *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
400 PROCESS_INFORMATION pi;
403 BackendParameters *param;
404 SECURITY_ATTRIBUTES
sa;
406 char paramHandleStr[32];
409 paramsz = SizeOfBackendParameters(startup_data_len);
411 /* Resume here if we need to retry */
414 /* Set up shared memory for parameter passing */
415 ZeroMemory(&
sa,
sizeof(
sa));
416 sa.nLength =
sizeof(
sa);
417 sa.bInheritHandle = TRUE;
418 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
424 if (paramHandle == INVALID_HANDLE_VALUE)
427 (
errmsg(
"could not create backend parameter file mapping: error code %lu",
431 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
435 (
errmsg(
"could not map backend parameter memory: error code %lu",
437 CloseHandle(paramHandle);
441 /* Format the cmd line */
443 sprintf(paramHandleStr,
"%llu", (LONG_PTR) paramHandle);
445 sprintf(paramHandleStr,
"%lu", (DWORD) paramHandle);
447 l =
snprintf(cmdLine,
sizeof(cmdLine) - 1,
"\"%s\" --forkchild=\"%s\" %s",
448 postgres_exec_path, child_kind, paramHandleStr);
449 if (l >=
sizeof(cmdLine))
452 (
errmsg(
"subprocess command line too long")));
453 UnmapViewOfFile(param);
454 CloseHandle(paramHandle);
458 memset(&pi, 0,
sizeof(pi));
459 memset(&si, 0,
sizeof(si));
463 * Create the subprocess in a suspended state. This will be resumed later,
464 * once we have written out the parameter file.
466 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
467 NULL, NULL, &si, &pi))
470 (
errmsg(
"CreateProcess() call failed: %m (error code %lu)",
472 UnmapViewOfFile(param);
473 CloseHandle(paramHandle);
477 if (!save_backend_variables(param, child_slot, client_sock,
478 pi.hProcess, pi.dwProcessId,
479 startup_data, startup_data_len))
482 * log made by save_backend_variables, but we have to clean up the
483 * mess with the half-started process
485 if (!TerminateProcess(pi.hProcess, 255))
487 (
errmsg_internal(
"could not terminate unstarted process: error code %lu",
489 CloseHandle(pi.hProcess);
490 CloseHandle(pi.hThread);
491 UnmapViewOfFile(param);
492 CloseHandle(paramHandle);
493 return -1;
/* log made by save_backend_variables */
496 /* Drop the parameter shared memory that is now inherited to the backend */
497 if (!UnmapViewOfFile(param))
499 (
errmsg(
"could not unmap view of backend parameter file: error code %lu",
501 if (!CloseHandle(paramHandle))
503 (
errmsg(
"could not close handle to backend parameter file: error code %lu",
507 * Reserve the memory region used by our main shared memory segment before
508 * we resume the child process. Normally this should succeed, but if ASLR
509 * is active then it might sometimes fail due to the stack or heap having
510 * gotten mapped into that range. In that case, just terminate the
515 /* pgwin32_ReserveSharedMemoryRegion already made a log entry */
516 if (!TerminateProcess(pi.hProcess, 255))
518 (
errmsg_internal(
"could not terminate process that failed to reserve memory: error code %lu",
520 CloseHandle(pi.hProcess);
521 CloseHandle(pi.hThread);
522 if (++retry_count < 100)
525 (
errmsg(
"giving up after too many tries to reserve shared memory"),
526 errhint(
"This might be caused by ASLR or antivirus software.")));
531 * Now that the backend variables are written out, we start the child
532 * thread so it can start initializing while we set up the rest of the
535 if (ResumeThread(pi.hThread) == -1)
537 if (!TerminateProcess(pi.hProcess, 255))
540 (
errmsg_internal(
"could not terminate unstartable process: error code %lu",
542 CloseHandle(pi.hProcess);
543 CloseHandle(pi.hThread);
546 CloseHandle(pi.hProcess);
547 CloseHandle(pi.hThread);
549 (
errmsg_internal(
"could not resume thread of unstarted process: error code %lu",
554 /* Set up notification when the child process dies */
555 pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
557 /* Don't close pi.hProcess, it's owned by the deadchild callback now */
559 CloseHandle(pi.hThread);
561 return pi.dwProcessId;
566 * SubPostmasterMain -- Get the fork/exec'd process into a state equivalent
567 * to what it would be if we'd simply forked on Unix, and then
568 * dispatch to the appropriate place.
570 * The first two command line arguments are expected to be "--forkchild=<name>",
571 * where <name> indicates which postmaster child we are to become, and
572 * the name of a variables file that we can read to load data that would
573 * have been inherited by fork() on Unix.
576SubPostmasterMain(
int argc,
char *argv[])
579 size_t startup_data_len;
585 /* In EXEC_BACKEND case we will not have inherited these settings */
590 * Capture the end of process creation for logging. We don't include the
591 * time spent copying data from shared memory and setting up the backend.
595 /* Setup essential subsystems (to ensure elog() behaves sanely) */
598 /* Check we got appropriate args */
600 elog(
FATAL,
"invalid subpostmaster invocation");
602 /* Find the entry in child_process_kinds */
603 if (strncmp(argv[1],
"--forkchild=", 12) != 0)
604 elog(
FATAL,
"invalid subpostmaster invocation (--forkchild argument missing)");
605 child_kind = argv[1] + 12;
617 elog(
ERROR,
"unknown child kind %s", child_kind);
619 /* Read in the variables file */
620 read_backend_variables(argv[2], &startup_data, &startup_data_len);
622 /* Close the postmaster's sockets (as soon as we know them) */
625 /* Setup as postmaster child */
629 * If appropriate, physically re-attach to shared memory segment. We want
630 * to do this before going any further to ensure that we can attach at the
631 * same address the postmaster used. On the other hand, if we choose not
632 * to re-attach, we may have other cleanup to do.
634 * If testing EXEC_BACKEND on Linux, you should run this as root before
635 * starting the postmaster:
637 * sysctl -w kernel.randomize_va_space=0
639 * This prevents using randomized stack and code addresses that cause the
640 * child process's memory map to be different from the parent's, making it
641 * sometimes impossible to attach to shared memory at the desired address.
642 * Return the setting to its old value (usually '1' or '2') when finished.
649 /* Read in remaining GUC variables */
650 read_nondefault_variables();
652 /* Capture and transfer timings that may be needed for log_connections */
663 * Check that the data directory looks valid, which will also check the
664 * privileges on the data directory and update our umask and file/group
665 * variables for creating files later. Note: this should really be done
666 * before we create any files or directories.
671 * (re-)read control file, as it contains config. The postmaster will
672 * already have read this, but this process doesn't know about that.
677 * Reload any libraries that were preloaded by the postmaster. Since we
678 * exec'd this process, those libraries didn't come along with us; but we
679 * should load them into all child processes to be consistent with the
680 * non-EXEC_BACKEND behavior.
684 /* Restore basic shared memory pointers */
689 * Run the appropriate Main function
696#define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
697#define read_inheritable_socket(dest, src) (*(dest) = *(src))
699static bool write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE child);
700static bool write_inheritable_socket(InheritableSocket *
dest, SOCKET src,
702static void read_inheritable_socket(SOCKET *
dest, InheritableSocket *src);
706/* Save critical backend variables into the BackendParameters struct */
708save_backend_variables(BackendParameters *param,
711 HANDLE childProcess, pid_t childPid,
713 const void *startup_data,
size_t startup_data_len)
716 memcpy(¶m->client_sock, client_sock,
sizeof(
ClientSocket));
719 if (!write_inheritable_socket(¶m->inh_sock,
726 param->MyPMChildSlot = child_slot;
736#ifdef USE_INJECTION_POINTS
737 param->ActiveInjectionPoints = ActiveInjectionPoints;
766 param->PostmasterHandle = PostmasterHandle;
767 if (!write_duplicated_handle(¶m->initial_signal_pipe,
782 param->startup_data_len = startup_data_len;
783 if (startup_data_len > 0)
784 memcpy(param->startup_data, startup_data, startup_data_len);
791 * Duplicate a handle for usage in a child process, and write the child
792 * process instance of the handle to the parameter file.
795write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE childProcess)
797 HANDLE hChild = INVALID_HANDLE_VALUE;
799 if (!DuplicateHandle(GetCurrentProcess(),
805 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
808 (
errmsg_internal(
"could not duplicate handle to be written to backend parameter file: error code %lu",
818 * Duplicate a socket for usage in a child process, and write the resulting
819 * structure to the parameter file.
820 * This is required because a number of LSPs (Layered Service Providers) very
821 * common on Windows (antivirus, firewalls, download managers etc) break
822 * straight socket inheritance.
825write_inheritable_socket(InheritableSocket *
dest, SOCKET src, pid_t childpid)
827 dest->origsocket = src;
831 if (WSADuplicateSocket(src, childpid, &
dest->wsainfo) != 0)
834 (
errmsg(
"could not duplicate socket %d for use in backend: error code %d",
835 (
int) src, WSAGetLastError())));
843 * Read a duplicate socket structure back, and get the socket descriptor.
846read_inheritable_socket(SOCKET *
dest, InheritableSocket *src)
852 /* Not a real socket! */
853 *
dest = src->origsocket;
857 /* Actual socket, so create from structure */
858 s = WSASocket(FROM_PROTOCOL_INFO,
864 if (s == INVALID_SOCKET)
866 write_stderr(
"could not create inherited socket: error code %d\n",
873 * To make sure we don't get two references to the same socket, close
874 * the original one. (This would happen when inheritance actually
883read_backend_variables(
char *
id,
void **startup_data,
size_t *startup_data_len)
885 BackendParameters param;
888 /* Non-win32 implementation reads from file */
895 write_stderr(
"could not open backend variables file \"%s\": %m\n",
id);
899 if (fread(¶m,
sizeof(param), 1, fp) != 1)
901 write_stderr(
"could not read from backend variables file \"%s\": %m\n",
id);
905 /* read startup data */
906 *startup_data_len = param.startup_data_len;
907 if (param.startup_data_len > 0)
909 *startup_data =
palloc(*startup_data_len);
910 if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
912 write_stderr(
"could not read startup data from backend variables file \"%s\": %m\n",
918 *startup_data = NULL;
928 /* Win32 version uses mapped file */
930 BackendParameters *paramp;
933 paramHandle = (HANDLE) _atoi64(
id);
935 paramHandle = (HANDLE) atol(
id);
937 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
940 write_stderr(
"could not map view of backend variables: error code %lu\n",
945 memcpy(¶m, paramp,
sizeof(BackendParameters));
947 /* read startup data */
948 *startup_data_len = param.startup_data_len;
949 if (param.startup_data_len > 0)
951 *startup_data =
palloc(paramp->startup_data_len);
952 memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
955 *startup_data = NULL;
957 if (!UnmapViewOfFile(paramp))
959 write_stderr(
"could not unmap view of backend variables: error code %lu\n",
964 if (!CloseHandle(paramHandle))
966 write_stderr(
"could not close handle to backend parameter variables: error code %lu\n",
972 restore_backend_variables(¶m);
975/* Restore critical backend variables from the BackendParameters struct */
977restore_backend_variables(BackendParameters *param)
998#ifdef USE_INJECTION_POINTS
999 ActiveInjectionPoints = param->ActiveInjectionPoints;
1028 PostmasterHandle = param->PostmasterHandle;
1042 * We need to restore fd.c's counts of externally-opened FDs; to avoid
1043 * confusion, be sure to do this after restoring max_safe_fds. (Note:
1044 * BackendInitialize will handle this for (*client_sock)->sock.)
1054#endif /* EXEC_BACKEND */
Datum idx(PG_FUNCTION_ARGS)
TimestampTz GetCurrentTimestamp(void)
ConnectionTiming conn_timing
#define write_stderr(str)
#define FLEXIBLE_ARRAY_MEMBER
void dsm_detach_all(void)
int errmsg_internal(const char *fmt,...)
int errcode_for_file_access(void)
int errhint(const char *fmt,...)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
int MakePGDirectory(const char *directoryName)
void ReserveExternalFD(void)
FILE * AllocateFile(const char *name, const char *mode)
#define PG_TEMP_FILES_DIR
#define PG_TEMP_FILE_PREFIX
struct ClientSocket * MyClientSocket
char pkglib_path[MAXPGPATH]
bool IsPostmasterEnvironment
char my_exec_path[MAXPGPATH]
void InitializeGUCOptions(void)
Assert(PointerIsAligned(start, uint64))
static child_process_kind child_process_kinds[]
const char * PostmasterChildName(BackendType child_type)
pid_t postmaster_child_launch(BackendType child_type, int child_slot, void *startup_data, size_t startup_data_len, ClientSocket *client_sock)
char ** LWLockTrancheNames
int NamedLWLockTrancheRequests
NamedLWLockTrancheRequest * NamedLWLockTrancheRequestArray
LWLockPadded * MainLWLockArray
void * MemoryContextAlloc(MemoryContext context, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
#define IsExternalConnectionBackend(backend_type)
void InitPostmasterChild(void)
void process_shared_preload_libraries(void)
void SetDataDir(const char *dir)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
NON_EXEC_STATIC int num_pmchild_slots
NON_EXEC_STATIC volatile PMSignalData * PMSignalState
size_t strlcpy(char *dst, const char *src, size_t siz)
CommandDest whereToSendOutput
int postmaster_alive_fds[2]
void ClosePostmasterPorts(bool am_syslogger)
NON_EXEC_STATIC ProcSignalHeader * ProcSignal
void InitShmemAccess(PGShmemHeader *seghdr)
HANDLE pgwin32_create_signal_listener(pid_t pid)
HANDLE pgwin32_initial_signal_pipe
PGPROC * PreparedXactProcs
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
NON_EXEC_STATIC slock_t * ProcStructLock
TimestampTz socket_create
void(* main_fn)(const void *startup_data, size_t startup_data_len)
NON_EXEC_STATIC pg_time_t first_syslogger_file_time
void PGSharedMemoryDetach(void)
unsigned long UsedShmemSegID
void PGSharedMemoryReAttach(void)
void * ShmemProtectiveRegion
int pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
void PGSharedMemoryNoReAttach(void)
void LocalProcessControlFile(bool reset)