80 WSAPROTOCOL_INFO wsainfo;
83typedef int InheritableSocket;
100#ifdef USE_INJECTION_POINTS
101 struct InjectionPointsCtl *ActiveInjectionPoints;
123 HANDLE PostmasterHandle;
124 HANDLE initial_signal_pipe;
142 InheritableSocket inh_sock;
147 size_t startup_data_len;
151#define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
153static void read_backend_variables(
char *
id,
void **startup_data,
size_t *startup_data_len);
154static void restore_backend_variables(BackendParameters *param);
156static bool save_backend_variables(BackendParameters *param,
int child_slot,
159 HANDLE childProcess, pid_t childPid,
161 const void *startup_data,
size_t startup_data_len);
163static pid_t internal_forkexec(
const char *child_kind,
int child_slot,
164 const void *startup_data,
size_t startup_data_len,
175 void (*main_fn) (
const void *startup_data,
size_t startup_data_len);
230 const void *startup_data,
size_t startup_data_len,
243 startup_data, startup_data_len, client_sock);
307internal_forkexec(
const char *child_kind,
int child_slot,
308 const void *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
310 static unsigned long tmpBackendFileNum = 0;
314 BackendParameters *param;
326 paramsz = SizeOfBackendParameters(startup_data_len);
328 if (!save_backend_variables(param, child_slot, client_sock, startup_data, startup_data_len))
354 errmsg(
"could not create file \"%s\": %m",
361 if (fwrite(param, paramsz, 1, fp) != 1)
365 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
377 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
382 argv[0] =
"postgres";
386 argv[2] = tmpfilename;
392 if (execv(postgres_exec_path, argv) < 0)
395 (
errmsg(
"could not execute server process \"%s\": %m",
396 postgres_exec_path)));
417internal_forkexec(
const char *child_kind,
int child_slot,
418 const void *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
422 PROCESS_INFORMATION pi;
425 BackendParameters *param;
426 SECURITY_ATTRIBUTES
sa;
428 char paramHandleStr[32];
431 paramsz = SizeOfBackendParameters(startup_data_len);
437 ZeroMemory(&
sa,
sizeof(
sa));
438 sa.nLength =
sizeof(
sa);
439 sa.bInheritHandle = TRUE;
440 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
446 if (paramHandle == INVALID_HANDLE_VALUE)
449 (
errmsg(
"could not create backend parameter file mapping: error code %lu",
453 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
457 (
errmsg(
"could not map backend parameter memory: error code %lu",
459 CloseHandle(paramHandle);
465 sprintf(paramHandleStr,
"%llu", (LONG_PTR) paramHandle);
467 sprintf(paramHandleStr,
"%lu", (DWORD) paramHandle);
469 l =
snprintf(cmdLine,
sizeof(cmdLine) - 1,
"\"%s\" --forkchild=\"%s\" %s",
470 postgres_exec_path, child_kind, paramHandleStr);
471 if (l >=
sizeof(cmdLine))
474 (
errmsg(
"subprocess command line too long")));
475 UnmapViewOfFile(param);
476 CloseHandle(paramHandle);
480 memset(&pi, 0,
sizeof(pi));
481 memset(&si, 0,
sizeof(si));
488 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
489 NULL, NULL, &si, &pi))
492 (
errmsg(
"CreateProcess() call failed: %m (error code %lu)",
494 UnmapViewOfFile(param);
495 CloseHandle(paramHandle);
499 if (!save_backend_variables(param, child_slot, client_sock,
500 pi.hProcess, pi.dwProcessId,
501 startup_data, startup_data_len))
507 if (!TerminateProcess(pi.hProcess, 255))
509 (
errmsg_internal(
"could not terminate unstarted process: error code %lu",
511 CloseHandle(pi.hProcess);
512 CloseHandle(pi.hThread);
513 UnmapViewOfFile(param);
514 CloseHandle(paramHandle);
519 if (!UnmapViewOfFile(param))
521 (
errmsg(
"could not unmap view of backend parameter file: error code %lu",
523 if (!CloseHandle(paramHandle))
525 (
errmsg(
"could not close handle to backend parameter file: error code %lu",
538 if (!TerminateProcess(pi.hProcess, 255))
540 (
errmsg_internal(
"could not terminate process that failed to reserve memory: error code %lu",
542 CloseHandle(pi.hProcess);
543 CloseHandle(pi.hThread);
544 if (++retry_count < 100)
547 (
errmsg(
"giving up after too many tries to reserve shared memory"),
548 errhint(
"This might be caused by ASLR or antivirus software.")));
557 if (ResumeThread(pi.hThread) == -1)
559 if (!TerminateProcess(pi.hProcess, 255))
562 (
errmsg_internal(
"could not terminate unstartable process: error code %lu",
564 CloseHandle(pi.hProcess);
565 CloseHandle(pi.hThread);
568 CloseHandle(pi.hProcess);
569 CloseHandle(pi.hThread);
571 (
errmsg_internal(
"could not resume thread of unstarted process: error code %lu",
577 pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
581 CloseHandle(pi.hThread);
583 return pi.dwProcessId;
598SubPostmasterMain(
int argc,
char *argv[])
601 size_t startup_data_len;
622 elog(
FATAL,
"invalid subpostmaster invocation");
625 if (strncmp(argv[1],
"--forkchild=", 12) != 0)
626 elog(
FATAL,
"invalid subpostmaster invocation (--forkchild argument missing)");
627 child_kind = argv[1] + 12;
639 elog(
ERROR,
"unknown child kind %s", child_kind);
642 read_backend_variables(argv[2], &startup_data, &startup_data_len);
672 read_nondefault_variables();
718#define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
719#define read_inheritable_socket(dest, src) (*(dest) = *(src))
721static bool write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE child);
722static bool write_inheritable_socket(InheritableSocket *
dest, SOCKET src,
724static void read_inheritable_socket(SOCKET *
dest, InheritableSocket *src);
730save_backend_variables(BackendParameters *param,
733 HANDLE childProcess, pid_t childPid,
735 const void *startup_data,
size_t startup_data_len)
738 memcpy(¶m->client_sock, client_sock,
sizeof(
ClientSocket));
741 if (!write_inheritable_socket(¶m->inh_sock,
748 param->MyPMChildSlot = child_slot;
758#ifdef USE_INJECTION_POINTS
759 param->ActiveInjectionPoints = ActiveInjectionPoints;
786 param->PostmasterHandle = PostmasterHandle;
787 if (!write_duplicated_handle(¶m->initial_signal_pipe,
802 param->startup_data_len = startup_data_len;
803 if (startup_data_len > 0)
804 memcpy(param->startup_data, startup_data, startup_data_len);
815write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE childProcess)
817 HANDLE hChild = INVALID_HANDLE_VALUE;
819 if (!DuplicateHandle(GetCurrentProcess(),
825 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
828 (
errmsg_internal(
"could not duplicate handle to be written to backend parameter file: error code %lu",
845write_inheritable_socket(InheritableSocket *
dest, SOCKET src, pid_t childpid)
847 dest->origsocket = src;
851 if (WSADuplicateSocket(src, childpid, &
dest->wsainfo) != 0)
854 (
errmsg(
"could not duplicate socket %d for use in backend: error code %d",
855 (
int) src, WSAGetLastError())));
866read_inheritable_socket(SOCKET *
dest, InheritableSocket *src)
873 *
dest = src->origsocket;
878 s = WSASocket(FROM_PROTOCOL_INFO,
884 if (s == INVALID_SOCKET)
886 write_stderr(
"could not create inherited socket: error code %d\n",
903read_backend_variables(
char *
id,
void **startup_data,
size_t *startup_data_len)
905 BackendParameters param;
915 write_stderr(
"could not open backend variables file \"%s\": %m\n",
id);
919 if (fread(¶m,
sizeof(param), 1, fp) != 1)
921 write_stderr(
"could not read from backend variables file \"%s\": %m\n",
id);
926 *startup_data_len = param.startup_data_len;
927 if (param.startup_data_len > 0)
929 *startup_data =
palloc(*startup_data_len);
930 if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
932 write_stderr(
"could not read startup data from backend variables file \"%s\": %m\n",
938 *startup_data = NULL;
950 BackendParameters *paramp;
953 paramHandle = (HANDLE) _atoi64(
id);
955 paramHandle = (HANDLE) atol(
id);
957 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
960 write_stderr(
"could not map view of backend variables: error code %lu\n",
965 memcpy(¶m, paramp,
sizeof(BackendParameters));
968 *startup_data_len = param.startup_data_len;
969 if (param.startup_data_len > 0)
971 *startup_data =
palloc(paramp->startup_data_len);
972 memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
975 *startup_data = NULL;
977 if (!UnmapViewOfFile(paramp))
979 write_stderr(
"could not unmap view of backend variables: error code %lu\n",
984 if (!CloseHandle(paramHandle))
986 write_stderr(
"could not close handle to backend parameter variables: error code %lu\n",
992 restore_backend_variables(¶m);
997restore_backend_variables(BackendParameters *param)
1018#ifdef USE_INJECTION_POINTS
1019 ActiveInjectionPoints = param->ActiveInjectionPoints;
1046 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
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)