80 WSAPROTOCOL_INFO wsainfo;
83typedef int InheritableSocket;
100#ifdef USE_INJECTION_POINTS
101 struct InjectionPointsCtl *ActiveInjectionPoints;
124 HANDLE PostmasterHandle;
125 HANDLE initial_signal_pipe;
143 InheritableSocket inh_sock;
148 size_t startup_data_len;
152#define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
154static void read_backend_variables(
char *
id,
void **startup_data,
size_t *startup_data_len);
155static void restore_backend_variables(BackendParameters *param);
157static bool save_backend_variables(BackendParameters *param,
int child_slot,
160 HANDLE childProcess, pid_t childPid,
162 const void *startup_data,
size_t startup_data_len);
164static pid_t internal_forkexec(
const char *child_kind,
int child_slot,
165 const void *startup_data,
size_t startup_data_len,
176 void (*main_fn) (
const void *startup_data,
size_t startup_data_len);
231 const void *startup_data,
size_t startup_data_len,
244 startup_data, startup_data_len, client_sock);
308internal_forkexec(
const char *child_kind,
int child_slot,
309 const void *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
311 static unsigned long tmpBackendFileNum = 0;
315 BackendParameters *param;
327 paramsz = SizeOfBackendParameters(startup_data_len);
329 if (!save_backend_variables(param, child_slot, client_sock, startup_data, startup_data_len))
355 errmsg(
"could not create file \"%s\": %m",
362 if (fwrite(param, paramsz, 1, fp) != 1)
366 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
378 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
383 argv[0] =
"postgres";
387 argv[2] = tmpfilename;
393 if (execv(postgres_exec_path, argv) < 0)
396 (
errmsg(
"could not execute server process \"%s\": %m",
397 postgres_exec_path)));
418internal_forkexec(
const char *child_kind,
int child_slot,
419 const void *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
423 PROCESS_INFORMATION pi;
426 BackendParameters *param;
427 SECURITY_ATTRIBUTES
sa;
429 char paramHandleStr[32];
432 paramsz = SizeOfBackendParameters(startup_data_len);
438 ZeroMemory(&
sa,
sizeof(
sa));
439 sa.nLength =
sizeof(
sa);
440 sa.bInheritHandle = TRUE;
441 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
447 if (paramHandle == INVALID_HANDLE_VALUE)
450 (
errmsg(
"could not create backend parameter file mapping: error code %lu",
454 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
458 (
errmsg(
"could not map backend parameter memory: error code %lu",
460 CloseHandle(paramHandle);
466 sprintf(paramHandleStr,
"%llu", (LONG_PTR) paramHandle);
468 sprintf(paramHandleStr,
"%lu", (DWORD) paramHandle);
470 l =
snprintf(cmdLine,
sizeof(cmdLine) - 1,
"\"%s\" --forkchild=\"%s\" %s",
471 postgres_exec_path, child_kind, paramHandleStr);
472 if (l >=
sizeof(cmdLine))
475 (
errmsg(
"subprocess command line too long")));
476 UnmapViewOfFile(param);
477 CloseHandle(paramHandle);
481 memset(&pi, 0,
sizeof(pi));
482 memset(&si, 0,
sizeof(si));
489 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
490 NULL, NULL, &si, &pi))
493 (
errmsg(
"CreateProcess() call failed: %m (error code %lu)",
495 UnmapViewOfFile(param);
496 CloseHandle(paramHandle);
500 if (!save_backend_variables(param, child_slot, client_sock,
501 pi.hProcess, pi.dwProcessId,
502 startup_data, startup_data_len))
508 if (!TerminateProcess(pi.hProcess, 255))
510 (
errmsg_internal(
"could not terminate unstarted process: error code %lu",
512 CloseHandle(pi.hProcess);
513 CloseHandle(pi.hThread);
514 UnmapViewOfFile(param);
515 CloseHandle(paramHandle);
520 if (!UnmapViewOfFile(param))
522 (
errmsg(
"could not unmap view of backend parameter file: error code %lu",
524 if (!CloseHandle(paramHandle))
526 (
errmsg(
"could not close handle to backend parameter file: error code %lu",
539 if (!TerminateProcess(pi.hProcess, 255))
541 (
errmsg_internal(
"could not terminate process that failed to reserve memory: error code %lu",
543 CloseHandle(pi.hProcess);
544 CloseHandle(pi.hThread);
545 if (++retry_count < 100)
548 (
errmsg(
"giving up after too many tries to reserve shared memory"),
549 errhint(
"This might be caused by ASLR or antivirus software.")));
558 if (ResumeThread(pi.hThread) == -1)
560 if (!TerminateProcess(pi.hProcess, 255))
563 (
errmsg_internal(
"could not terminate unstartable process: error code %lu",
565 CloseHandle(pi.hProcess);
566 CloseHandle(pi.hThread);
569 CloseHandle(pi.hProcess);
570 CloseHandle(pi.hThread);
572 (
errmsg_internal(
"could not resume thread of unstarted process: error code %lu",
578 pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
582 CloseHandle(pi.hThread);
584 return pi.dwProcessId;
599SubPostmasterMain(
int argc,
char *argv[])
602 size_t startup_data_len;
623 elog(
FATAL,
"invalid subpostmaster invocation");
626 if (strncmp(argv[1],
"--forkchild=", 12) != 0)
627 elog(
FATAL,
"invalid subpostmaster invocation (--forkchild argument missing)");
628 child_kind = argv[1] + 12;
640 elog(
ERROR,
"unknown child kind %s", child_kind);
643 read_backend_variables(argv[2], &startup_data, &startup_data_len);
673 read_nondefault_variables();
719#define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
720#define read_inheritable_socket(dest, src) (*(dest) = *(src))
722static bool write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE child);
723static bool write_inheritable_socket(InheritableSocket *
dest, SOCKET src,
725static void read_inheritable_socket(SOCKET *
dest, InheritableSocket *src);
731save_backend_variables(BackendParameters *param,
734 HANDLE childProcess, pid_t childPid,
736 const void *startup_data,
size_t startup_data_len)
739 memcpy(¶m->client_sock, client_sock,
sizeof(
ClientSocket));
742 if (!write_inheritable_socket(¶m->inh_sock,
749 param->MyPMChildSlot = child_slot;
759#ifdef USE_INJECTION_POINTS
760 param->ActiveInjectionPoints = ActiveInjectionPoints;
788 param->PostmasterHandle = PostmasterHandle;
789 if (!write_duplicated_handle(¶m->initial_signal_pipe,
804 param->startup_data_len = startup_data_len;
805 if (startup_data_len > 0)
806 memcpy(param->startup_data, startup_data, startup_data_len);
817write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE childProcess)
819 HANDLE hChild = INVALID_HANDLE_VALUE;
821 if (!DuplicateHandle(GetCurrentProcess(),
827 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
830 (
errmsg_internal(
"could not duplicate handle to be written to backend parameter file: error code %lu",
847write_inheritable_socket(InheritableSocket *
dest, SOCKET src, pid_t childpid)
849 dest->origsocket = src;
853 if (WSADuplicateSocket(src, childpid, &
dest->wsainfo) != 0)
856 (
errmsg(
"could not duplicate socket %d for use in backend: error code %d",
857 (
int) src, WSAGetLastError())));
868read_inheritable_socket(SOCKET *
dest, InheritableSocket *src)
875 *
dest = src->origsocket;
880 s = WSASocket(FROM_PROTOCOL_INFO,
886 if (s == INVALID_SOCKET)
888 write_stderr(
"could not create inherited socket: error code %d\n",
905read_backend_variables(
char *
id,
void **startup_data,
size_t *startup_data_len)
907 BackendParameters param;
917 write_stderr(
"could not open backend variables file \"%s\": %m\n",
id);
921 if (fread(¶m,
sizeof(param), 1, fp) != 1)
923 write_stderr(
"could not read from backend variables file \"%s\": %m\n",
id);
928 *startup_data_len = param.startup_data_len;
929 if (param.startup_data_len > 0)
931 *startup_data =
palloc(*startup_data_len);
932 if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
934 write_stderr(
"could not read startup data from backend variables file \"%s\": %m\n",
940 *startup_data = NULL;
952 BackendParameters *paramp;
955 paramHandle = (HANDLE) _atoi64(
id);
957 paramHandle = (HANDLE) atol(
id);
959 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
962 write_stderr(
"could not map view of backend variables: error code %lu\n",
967 memcpy(¶m, paramp,
sizeof(BackendParameters));
970 *startup_data_len = param.startup_data_len;
971 if (param.startup_data_len > 0)
973 *startup_data =
palloc(paramp->startup_data_len);
974 memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
977 *startup_data = NULL;
979 if (!UnmapViewOfFile(paramp))
981 write_stderr(
"could not unmap view of backend variables: error code %lu\n",
986 if (!CloseHandle(paramHandle))
988 write_stderr(
"could not close handle to backend parameter variables: error code %lu\n",
994 restore_backend_variables(¶m);
999restore_backend_variables(BackendParameters *param)
1020#ifdef USE_INJECTION_POINTS
1021 ActiveInjectionPoints = param->ActiveInjectionPoints;
1049 PostmasterHandle = param->PostmasterHandle;
Datum idx(PG_FUNCTION_ARGS)
void AutoVacLauncherMain(const void *startup_data, size_t startup_data_len)
void AutoVacWorkerMain(const void *startup_data, size_t startup_data_len)
void StartupProcessMain(const void *startup_data, size_t startup_data_len)
TimestampTz GetCurrentTimestamp(void)
ConnectionTiming conn_timing
void BackendMain(const void *startup_data, size_t startup_data_len)
void BackgroundWorkerMain(const void *startup_data, size_t startup_data_len)
void BackgroundWriterMain(const void *startup_data, size_t startup_data_len)
#define write_stderr(str)
#define FLEXIBLE_ARRAY_MEMBER
void CheckpointerMain(const void *startup_data, size_t startup_data_len)
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))
pid_t postmaster_child_launch(BackendType child_type, int child_slot, const void *startup_data, size_t startup_data_len, ClientSocket *client_sock)
static child_process_kind child_process_kinds[]
const char * PostmasterChildName(BackendType child_type)
NamedLWLockTranche * NamedLWLockTrancheArray
int NamedLWLockTrancheRequests
LWLockPadded * MainLWLockArray
void * MemoryContextAlloc(MemoryContext context, Size size)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext TopMemoryContext
void IoWorkerMain(const void *startup_data, size_t startup_data_len)
#define IsExternalConnectionBackend(backend_type)
void InitPostmasterChild(void)
void process_shared_preload_libraries(void)
void SetDataDir(const char *dir)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
void PgArchiverMain(const void *startup_data, size_t startup_data_len)
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
bool query_id_squash_values
void InitShmemAccess(PGShmemHeader *seghdr)
HANDLE pgwin32_create_signal_listener(pid_t pid)
HANDLE pgwin32_initial_signal_pipe
void ReplSlotSyncWorkerMain(const void *startup_data, size_t startup_data_len)
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)
void SysLoggerMain(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 WalReceiverMain(const void *startup_data, size_t startup_data_len)
void WalSummarizerMain(const void *startup_data, size_t startup_data_len)
void WalWriterMain(const void *startup_data, size_t startup_data_len)
void PGSharedMemoryReAttach(void)
void * ShmemProtectiveRegion
int pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
void PGSharedMemoryNoReAttach(void)
void LocalProcessControlFile(bool reset)