79 WSAPROTOCOL_INFO wsainfo;
82 typedef int InheritableSocket;
99 #ifdef USE_INJECTION_POINTS
100 struct InjectionPointsCtl *ActiveInjectionPoints;
122 HANDLE PostmasterHandle;
123 HANDLE initial_signal_pipe;
141 InheritableSocket inh_sock;
146 size_t startup_data_len;
150 #define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
152 static void read_backend_variables(
char *
id,
char **startup_data,
size_t *startup_data_len);
153 static void restore_backend_variables(BackendParameters *param);
155 static bool save_backend_variables(BackendParameters *param,
int child_slot,
158 HANDLE childProcess, pid_t childPid,
160 char *startup_data,
size_t startup_data_len);
162 static pid_t internal_forkexec(
const char *child_kind,
int child_slot,
163 char *startup_data,
size_t startup_data_len,
228 char *startup_data,
size_t startup_data_len,
237 startup_data, startup_data_len, client_sock);
291 internal_forkexec(
const char *child_kind,
int child_slot,
292 char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
294 static unsigned long tmpBackendFileNum = 0;
298 BackendParameters *param;
310 paramsz = SizeOfBackendParameters(startup_data_len);
312 if (!save_backend_variables(param, child_slot, client_sock, startup_data, startup_data_len))
338 errmsg(
"could not create file \"%s\": %m",
345 if (fwrite(param, paramsz, 1, fp) != 1)
349 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
361 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
366 argv[0] =
"postgres";
370 argv[2] = tmpfilename;
376 if (execv(postgres_exec_path, argv) < 0)
379 (
errmsg(
"could not execute server process \"%s\": %m",
380 postgres_exec_path)));
401 internal_forkexec(
const char *child_kind,
int child_slot,
402 char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
406 PROCESS_INFORMATION pi;
409 BackendParameters *param;
410 SECURITY_ATTRIBUTES
sa;
412 char paramHandleStr[32];
415 paramsz = SizeOfBackendParameters(startup_data_len);
421 ZeroMemory(&
sa,
sizeof(
sa));
422 sa.nLength =
sizeof(
sa);
423 sa.bInheritHandle = TRUE;
424 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
430 if (paramHandle == INVALID_HANDLE_VALUE)
433 (
errmsg(
"could not create backend parameter file mapping: error code %lu",
437 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
441 (
errmsg(
"could not map backend parameter memory: error code %lu",
443 CloseHandle(paramHandle);
449 sprintf(paramHandleStr,
"%llu", (LONG_PTR) paramHandle);
451 sprintf(paramHandleStr,
"%lu", (DWORD) paramHandle);
453 l =
snprintf(cmdLine,
sizeof(cmdLine) - 1,
"\"%s\" --forkchild=\"%s\" %s",
454 postgres_exec_path, child_kind, paramHandleStr);
455 if (l >=
sizeof(cmdLine))
458 (
errmsg(
"subprocess command line too long")));
459 UnmapViewOfFile(param);
460 CloseHandle(paramHandle);
464 memset(&pi, 0,
sizeof(pi));
465 memset(&si, 0,
sizeof(si));
472 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
473 NULL, NULL, &si, &pi))
476 (
errmsg(
"CreateProcess() call failed: %m (error code %lu)",
478 UnmapViewOfFile(param);
479 CloseHandle(paramHandle);
483 if (!save_backend_variables(param, child_slot, client_sock,
484 pi.hProcess, pi.dwProcessId,
485 startup_data, startup_data_len))
491 if (!TerminateProcess(pi.hProcess, 255))
493 (
errmsg_internal(
"could not terminate unstarted process: error code %lu",
495 CloseHandle(pi.hProcess);
496 CloseHandle(pi.hThread);
497 UnmapViewOfFile(param);
498 CloseHandle(paramHandle);
503 if (!UnmapViewOfFile(param))
505 (
errmsg(
"could not unmap view of backend parameter file: error code %lu",
507 if (!CloseHandle(paramHandle))
509 (
errmsg(
"could not close handle to backend parameter file: error code %lu",
522 if (!TerminateProcess(pi.hProcess, 255))
524 (
errmsg_internal(
"could not terminate process that failed to reserve memory: error code %lu",
526 CloseHandle(pi.hProcess);
527 CloseHandle(pi.hThread);
528 if (++retry_count < 100)
531 (
errmsg(
"giving up after too many tries to reserve shared memory"),
532 errhint(
"This might be caused by ASLR or antivirus software.")));
541 if (ResumeThread(pi.hThread) == -1)
543 if (!TerminateProcess(pi.hProcess, 255))
546 (
errmsg_internal(
"could not terminate unstartable process: error code %lu",
548 CloseHandle(pi.hProcess);
549 CloseHandle(pi.hThread);
552 CloseHandle(pi.hProcess);
553 CloseHandle(pi.hThread);
555 (
errmsg_internal(
"could not resume thread of unstarted process: error code %lu",
561 pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
565 CloseHandle(pi.hThread);
567 return pi.dwProcessId;
582 SubPostmasterMain(
int argc,
char *argv[])
585 size_t startup_data_len;
599 elog(
FATAL,
"invalid subpostmaster invocation");
602 if (strncmp(argv[1],
"--forkchild=", 12) != 0)
603 elog(
FATAL,
"invalid subpostmaster invocation (--forkchild argument missing)");
604 child_kind = argv[1] + 12;
616 elog(
ERROR,
"unknown child kind %s", child_kind);
619 read_backend_variables(argv[2], &startup_data, &startup_data_len);
649 read_nondefault_variables();
685 #define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
686 #define read_inheritable_socket(dest, src) (*(dest) = *(src))
688 static bool write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE child);
689 static bool write_inheritable_socket(InheritableSocket *
dest, SOCKET src,
691 static void read_inheritable_socket(SOCKET *
dest, InheritableSocket *src);
697 save_backend_variables(BackendParameters *param,
700 HANDLE childProcess, pid_t childPid,
702 char *startup_data,
size_t startup_data_len)
705 memcpy(¶m->client_sock, client_sock,
sizeof(
ClientSocket));
708 if (!write_inheritable_socket(¶m->inh_sock,
715 param->MyPMChildSlot = child_slot;
725 #ifdef USE_INJECTION_POINTS
726 param->ActiveInjectionPoints = ActiveInjectionPoints;
753 param->PostmasterHandle = PostmasterHandle;
754 if (!write_duplicated_handle(¶m->initial_signal_pipe,
769 param->startup_data_len = startup_data_len;
770 if (startup_data_len > 0)
771 memcpy(param->startup_data, startup_data, startup_data_len);
782 write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE childProcess)
784 HANDLE hChild = INVALID_HANDLE_VALUE;
786 if (!DuplicateHandle(GetCurrentProcess(),
792 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
795 (
errmsg_internal(
"could not duplicate handle to be written to backend parameter file: error code %lu",
812 write_inheritable_socket(InheritableSocket *
dest, SOCKET src, pid_t childpid)
814 dest->origsocket = src;
818 if (WSADuplicateSocket(src, childpid, &
dest->wsainfo) != 0)
821 (
errmsg(
"could not duplicate socket %d for use in backend: error code %d",
822 (
int) src, WSAGetLastError())));
833 read_inheritable_socket(SOCKET *
dest, InheritableSocket *src)
840 *
dest = src->origsocket;
845 s = WSASocket(FROM_PROTOCOL_INFO,
851 if (s == INVALID_SOCKET)
853 write_stderr(
"could not create inherited socket: error code %d\n",
870 read_backend_variables(
char *
id,
char **startup_data,
size_t *startup_data_len)
872 BackendParameters param;
882 write_stderr(
"could not open backend variables file \"%s\": %m\n",
id);
886 if (fread(¶m,
sizeof(param), 1, fp) != 1)
888 write_stderr(
"could not read from backend variables file \"%s\": %m\n",
id);
893 *startup_data_len = param.startup_data_len;
894 if (param.startup_data_len > 0)
896 *startup_data =
palloc(*startup_data_len);
897 if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
899 write_stderr(
"could not read startup data from backend variables file \"%s\": %m\n",
905 *startup_data = NULL;
917 BackendParameters *paramp;
920 paramHandle = (HANDLE) _atoi64(
id);
922 paramHandle = (HANDLE) atol(
id);
924 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
927 write_stderr(
"could not map view of backend variables: error code %lu\n",
932 memcpy(¶m, paramp,
sizeof(BackendParameters));
935 *startup_data_len = param.startup_data_len;
936 if (param.startup_data_len > 0)
938 *startup_data =
palloc(paramp->startup_data_len);
939 memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
942 *startup_data = NULL;
944 if (!UnmapViewOfFile(paramp))
946 write_stderr(
"could not unmap view of backend variables: error code %lu\n",
951 if (!CloseHandle(paramHandle))
953 write_stderr(
"could not close handle to backend parameter variables: error code %lu\n",
959 restore_backend_variables(¶m);
964 restore_backend_variables(BackendParameters *param)
985 #ifdef USE_INJECTION_POINTS
986 ActiveInjectionPoints = param->ActiveInjectionPoints;
1013 PostmasterHandle = param->PostmasterHandle;
Datum idx(PG_FUNCTION_ARGS)
void AutoVacWorkerMain(char *startup_data, size_t startup_data_len)
void AutoVacLauncherMain(char *startup_data, size_t startup_data_len) pg_attribute_noreturn()
void StartupProcessMain(char *startup_data, size_t startup_data_len)
void BackendMain(char *startup_data, size_t startup_data_len)
void BackgroundWorkerMain(char *startup_data, size_t startup_data_len)
void BackgroundWriterMain(char *startup_data, size_t startup_data_len)
#define write_stderr(str)
#define Assert(condition)
#define pg_attribute_noreturn()
#define FLEXIBLE_ARRAY_MEMBER
void CheckpointerMain(char *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)
FILE * AllocateFile(const char *name, const char *mode)
void ReserveExternalFD(void)
#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)
static child_process_kind child_process_kinds[]
const char * PostmasterChildName(BackendType child_type)
pid_t postmaster_child_launch(BackendType child_type, int child_slot, char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
NamedLWLockTranche * NamedLWLockTrancheArray
int NamedLWLockTrancheRequests
LWLockPadded * MainLWLockArray
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * palloc0(Size size)
void * MemoryContextAlloc(MemoryContext context, Size size)
void InitPostmasterChild(void)
void process_shared_preload_libraries(void)
void SetDataDir(const char *dir)
void PgArchiverMain(char *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
MemoryContextSwitchTo(old_ctx)
void InitShmemAccess(PGShmemHeader *seghdr)
HANDLE pgwin32_create_signal_listener(pid_t pid)
HANDLE pgwin32_initial_signal_pipe
void ReplSlotSyncWorkerMain(char *startup_data, size_t startup_data_len)
PGPROC * PreparedXactProcs
NON_EXEC_STATIC PGPROC * AuxiliaryProcs
NON_EXEC_STATIC slock_t * ProcStructLock
void(* main_fn)(char *startup_data, size_t startup_data_len) pg_attribute_noreturn()
NON_EXEC_STATIC pg_time_t first_syslogger_file_time
void SysLoggerMain(char *startup_data, size_t startup_data_len)
void PGSharedMemoryDetach(void)
unsigned long UsedShmemSegID
void WalReceiverMain(char *startup_data, size_t startup_data_len)
void WalSummarizerMain(char *startup_data, size_t startup_data_len)
void WalWriterMain(char *startup_data, size_t startup_data_len)
void PGSharedMemoryReAttach(void)
void * ShmemProtectiveRegion
int pgwin32_ReserveSharedMemoryRegion(HANDLE hChild)
void PGSharedMemoryNoReAttach(void)
void LocalProcessControlFile(bool reset)