85 WSAPROTOCOL_INFO wsainfo;
88 typedef int InheritableSocket;
107 struct bkend *ShmemBackendArray;
108 #ifdef USE_INJECTION_POINTS
109 struct InjectionPointsCtl *ActiveInjectionPoints;
111 #ifndef HAVE_SPINLOCKS
132 HANDLE PostmasterHandle;
133 HANDLE initial_signal_pipe;
149 InheritableSocket inh_sock;
154 size_t startup_data_len;
158 #define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
160 static void read_backend_variables(
char *
id,
char **startup_data,
size_t *startup_data_len);
161 static void restore_backend_variables(BackendParameters *param);
163 static bool save_backend_variables(BackendParameters *param,
ClientSocket *client_sock,
165 HANDLE childProcess, pid_t childPid,
167 char *startup_data,
size_t startup_data_len);
169 static pid_t internal_forkexec(
const char *child_kind,
char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock);
231 char *startup_data,
size_t startup_data_len,
240 startup_data, startup_data_len, client_sock);
286 internal_forkexec(
const char *child_kind,
char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
288 static unsigned long tmpBackendFileNum = 0;
292 BackendParameters *param;
304 paramsz = SizeOfBackendParameters(startup_data_len);
306 if (!save_backend_variables(param, client_sock, startup_data, startup_data_len))
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)));
360 argv[0] =
"postgres";
364 argv[2] = tmpfilename;
370 if (execv(postgres_exec_path, argv) < 0)
373 (
errmsg(
"could not execute server process \"%s\": %m",
374 postgres_exec_path)));
395 internal_forkexec(
const char *child_kind,
char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
399 PROCESS_INFORMATION pi;
402 BackendParameters *param;
403 SECURITY_ATTRIBUTES
sa;
405 char paramHandleStr[32];
408 paramsz = SizeOfBackendParameters(startup_data_len);
414 ZeroMemory(&
sa,
sizeof(
sa));
415 sa.nLength =
sizeof(
sa);
416 sa.bInheritHandle = TRUE;
417 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
423 if (paramHandle == INVALID_HANDLE_VALUE)
426 (
errmsg(
"could not create backend parameter file mapping: error code %lu",
430 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
434 (
errmsg(
"could not map backend parameter memory: error code %lu",
436 CloseHandle(paramHandle);
442 sprintf(paramHandleStr,
"%llu", (LONG_PTR) paramHandle);
444 sprintf(paramHandleStr,
"%lu", (DWORD) paramHandle);
446 l =
snprintf(cmdLine,
sizeof(cmdLine) - 1,
"\"%s\" --forkchild=\"%s\" %s",
447 postgres_exec_path, child_kind, paramHandleStr);
448 if (l >=
sizeof(cmdLine))
451 (
errmsg(
"subprocess command line too long")));
452 UnmapViewOfFile(param);
453 CloseHandle(paramHandle);
457 memset(&pi, 0,
sizeof(pi));
458 memset(&si, 0,
sizeof(si));
465 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
466 NULL, NULL, &si, &pi))
469 (
errmsg(
"CreateProcess() call failed: %m (error code %lu)",
471 UnmapViewOfFile(param);
472 CloseHandle(paramHandle);
476 if (!save_backend_variables(param, client_sock, pi.hProcess, pi.dwProcessId, startup_data, startup_data_len))
482 if (!TerminateProcess(pi.hProcess, 255))
484 (
errmsg_internal(
"could not terminate unstarted process: error code %lu",
486 CloseHandle(pi.hProcess);
487 CloseHandle(pi.hThread);
488 UnmapViewOfFile(param);
489 CloseHandle(paramHandle);
494 if (!UnmapViewOfFile(param))
496 (
errmsg(
"could not unmap view of backend parameter file: error code %lu",
498 if (!CloseHandle(paramHandle))
500 (
errmsg(
"could not close handle to backend parameter file: error code %lu",
513 if (!TerminateProcess(pi.hProcess, 255))
515 (
errmsg_internal(
"could not terminate process that failed to reserve memory: error code %lu",
517 CloseHandle(pi.hProcess);
518 CloseHandle(pi.hThread);
519 if (++retry_count < 100)
522 (
errmsg(
"giving up after too many tries to reserve shared memory"),
523 errhint(
"This might be caused by ASLR or antivirus software.")));
532 if (ResumeThread(pi.hThread) == -1)
534 if (!TerminateProcess(pi.hProcess, 255))
537 (
errmsg_internal(
"could not terminate unstartable process: error code %lu",
539 CloseHandle(pi.hProcess);
540 CloseHandle(pi.hThread);
543 CloseHandle(pi.hProcess);
544 CloseHandle(pi.hThread);
546 (
errmsg_internal(
"could not resume thread of unstarted process: error code %lu",
552 pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
556 CloseHandle(pi.hThread);
558 return pi.dwProcessId;
573 SubPostmasterMain(
int argc,
char *argv[])
576 size_t startup_data_len;
590 elog(
FATAL,
"invalid subpostmaster invocation");
593 if (strncmp(argv[1],
"--forkchild=", 12) != 0)
594 elog(
FATAL,
"invalid subpostmaster invocation (--forkchild argument missing)");
595 child_kind = argv[1] + 12;
607 elog(
ERROR,
"unknown child kind %s", child_kind);
610 read_backend_variables(argv[2], &startup_data, &startup_data_len);
640 read_nondefault_variables();
676 #define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
677 #define read_inheritable_socket(dest, src) (*(dest) = *(src))
679 static bool write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE child);
680 static bool write_inheritable_socket(InheritableSocket *
dest, SOCKET src,
682 static void read_inheritable_socket(SOCKET *
dest, InheritableSocket *src);
688 save_backend_variables(BackendParameters *param,
ClientSocket *client_sock,
690 HANDLE childProcess, pid_t childPid,
692 char *startup_data,
size_t startup_data_len)
695 memcpy(¶m->client_sock, client_sock,
sizeof(
ClientSocket));
698 if (!write_inheritable_socket(¶m->inh_sock,
715 param->ShmemBackendArray = ShmemBackendArray;
717 #ifdef USE_INJECTION_POINTS
718 param->ActiveInjectionPoints = ActiveInjectionPoints;
721 #ifndef HAVE_SPINLOCKS
746 param->PostmasterHandle = PostmasterHandle;
747 if (!write_duplicated_handle(¶m->initial_signal_pipe,
762 param->startup_data_len = startup_data_len;
763 if (startup_data_len > 0)
764 memcpy(param->startup_data, startup_data, startup_data_len);
775 write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE childProcess)
777 HANDLE hChild = INVALID_HANDLE_VALUE;
779 if (!DuplicateHandle(GetCurrentProcess(),
785 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
788 (
errmsg_internal(
"could not duplicate handle to be written to backend parameter file: error code %lu",
805 write_inheritable_socket(InheritableSocket *
dest, SOCKET src, pid_t childpid)
807 dest->origsocket = src;
811 if (WSADuplicateSocket(src, childpid, &
dest->wsainfo) != 0)
814 (
errmsg(
"could not duplicate socket %d for use in backend: error code %d",
815 (
int) src, WSAGetLastError())));
826 read_inheritable_socket(SOCKET *
dest, InheritableSocket *src)
833 *
dest = src->origsocket;
838 s = WSASocket(FROM_PROTOCOL_INFO,
844 if (s == INVALID_SOCKET)
846 write_stderr(
"could not create inherited socket: error code %d\n",
863 read_backend_variables(
char *
id,
char **startup_data,
size_t *startup_data_len)
865 BackendParameters param;
875 write_stderr(
"could not open backend variables file \"%s\": %m\n",
id);
879 if (fread(¶m,
sizeof(param), 1, fp) != 1)
881 write_stderr(
"could not read from backend variables file \"%s\": %m\n",
id);
886 *startup_data_len = param.startup_data_len;
887 if (param.startup_data_len > 0)
889 *startup_data =
palloc(*startup_data_len);
890 if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
892 write_stderr(
"could not read startup data from backend variables file \"%s\": %m\n",
898 *startup_data = NULL;
910 BackendParameters *paramp;
913 paramHandle = (HANDLE) _atoi64(
id);
915 paramHandle = (HANDLE) atol(
id);
917 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
920 write_stderr(
"could not map view of backend variables: error code %lu\n",
925 memcpy(¶m, paramp,
sizeof(BackendParameters));
928 *startup_data_len = param.startup_data_len;
929 if (param.startup_data_len > 0)
931 *startup_data =
palloc(paramp->startup_data_len);
932 memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
935 *startup_data = NULL;
937 if (!UnmapViewOfFile(paramp))
939 write_stderr(
"could not unmap view of backend variables: error code %lu\n",
944 if (!CloseHandle(paramHandle))
946 write_stderr(
"could not close handle to backend parameter variables: error code %lu\n",
952 restore_backend_variables(¶m);
957 restore_backend_variables(BackendParameters *param)
978 ShmemBackendArray = param->ShmemBackendArray;
980 #ifdef USE_INJECTION_POINTS
981 ActiveInjectionPoints = param->ActiveInjectionPoints;
984 #ifndef HAVE_SPINLOCKS
1009 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)
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[]
pid_t postmaster_child_launch(BackendType child_type, char *startup_data, size_t startup_data_len, ClientSocket *client_sock)
const char * PostmasterChildName(BackendType child_type)
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 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)
MemoryContextSwitchTo(old_ctx)
void InitShmemAccess(void *seghdr)
HANDLE pgwin32_create_signal_listener(pid_t pid)
HANDLE pgwin32_initial_signal_pipe
void ReplSlotSyncWorkerMain(char *startup_data, size_t startup_data_len)
PGSemaphore * SpinlockSemaArray
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)
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)