84 WSAPROTOCOL_INFO wsainfo;
87 typedef int InheritableSocket;
106 struct bkend *ShmemBackendArray;
107 #ifndef HAVE_SPINLOCKS
128 HANDLE PostmasterHandle;
129 HANDLE initial_signal_pipe;
145 InheritableSocket inh_sock;
150 size_t startup_data_len;
154 #define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
156 static void read_backend_variables(
char *
id,
char **startup_data,
size_t *startup_data_len);
157 static void restore_backend_variables(BackendParameters *param);
159 static bool save_backend_variables(BackendParameters *param,
ClientSocket *client_sock,
161 HANDLE childProcess, pid_t childPid,
163 char *startup_data,
size_t startup_data_len);
165 static pid_t internal_forkexec(
const char *child_kind,
char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock);
227 char *startup_data,
size_t startup_data_len,
236 startup_data, startup_data_len, client_sock);
282 internal_forkexec(
const char *child_kind,
char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
284 static unsigned long tmpBackendFileNum = 0;
288 BackendParameters *param;
300 paramsz = SizeOfBackendParameters(startup_data_len);
302 if (!save_backend_variables(param, client_sock, startup_data, startup_data_len))
328 errmsg(
"could not create file \"%s\": %m",
335 if (fwrite(param, paramsz, 1, fp) != 1)
339 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
351 errmsg(
"could not write to file \"%s\": %m", tmpfilename)));
356 argv[0] =
"postgres";
360 argv[2] = tmpfilename;
366 if (execv(postgres_exec_path, argv) < 0)
369 (
errmsg(
"could not execute server process \"%s\": %m",
370 postgres_exec_path)));
391 internal_forkexec(
const char *child_kind,
char *startup_data,
size_t startup_data_len,
ClientSocket *client_sock)
395 PROCESS_INFORMATION pi;
398 BackendParameters *param;
399 SECURITY_ATTRIBUTES
sa;
401 char paramHandleStr[32];
404 paramsz = SizeOfBackendParameters(startup_data_len);
410 ZeroMemory(&
sa,
sizeof(
sa));
411 sa.nLength =
sizeof(
sa);
412 sa.bInheritHandle = TRUE;
413 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
419 if (paramHandle == INVALID_HANDLE_VALUE)
422 (
errmsg(
"could not create backend parameter file mapping: error code %lu",
426 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
430 (
errmsg(
"could not map backend parameter memory: error code %lu",
432 CloseHandle(paramHandle);
438 sprintf(paramHandleStr,
"%llu", (LONG_PTR) paramHandle);
440 sprintf(paramHandleStr,
"%lu", (DWORD) paramHandle);
442 l =
snprintf(cmdLine,
sizeof(cmdLine) - 1,
"\"%s\" --forkchild=\"%s\" %s",
443 postgres_exec_path, child_kind, paramHandleStr);
444 if (l >=
sizeof(cmdLine))
447 (
errmsg(
"subprocess command line too long")));
448 UnmapViewOfFile(param);
449 CloseHandle(paramHandle);
453 memset(&pi, 0,
sizeof(pi));
454 memset(&si, 0,
sizeof(si));
461 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
462 NULL, NULL, &si, &pi))
465 (
errmsg(
"CreateProcess() call failed: %m (error code %lu)",
467 UnmapViewOfFile(param);
468 CloseHandle(paramHandle);
472 if (!save_backend_variables(param, client_sock, pi.hProcess, pi.dwProcessId, startup_data, startup_data_len))
478 if (!TerminateProcess(pi.hProcess, 255))
480 (
errmsg_internal(
"could not terminate unstarted process: error code %lu",
482 CloseHandle(pi.hProcess);
483 CloseHandle(pi.hThread);
484 UnmapViewOfFile(param);
485 CloseHandle(paramHandle);
490 if (!UnmapViewOfFile(param))
492 (
errmsg(
"could not unmap view of backend parameter file: error code %lu",
494 if (!CloseHandle(paramHandle))
496 (
errmsg(
"could not close handle to backend parameter file: error code %lu",
509 if (!TerminateProcess(pi.hProcess, 255))
511 (
errmsg_internal(
"could not terminate process that failed to reserve memory: error code %lu",
513 CloseHandle(pi.hProcess);
514 CloseHandle(pi.hThread);
515 if (++retry_count < 100)
518 (
errmsg(
"giving up after too many tries to reserve shared memory"),
519 errhint(
"This might be caused by ASLR or antivirus software.")));
528 if (ResumeThread(pi.hThread) == -1)
530 if (!TerminateProcess(pi.hProcess, 255))
533 (
errmsg_internal(
"could not terminate unstartable process: error code %lu",
535 CloseHandle(pi.hProcess);
536 CloseHandle(pi.hThread);
539 CloseHandle(pi.hProcess);
540 CloseHandle(pi.hThread);
542 (
errmsg_internal(
"could not resume thread of unstarted process: error code %lu",
548 pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
552 CloseHandle(pi.hThread);
554 return pi.dwProcessId;
569 SubPostmasterMain(
int argc,
char *argv[])
572 size_t startup_data_len;
586 elog(
FATAL,
"invalid subpostmaster invocation");
589 if (strncmp(argv[1],
"--forkchild=", 12) != 0)
590 elog(
FATAL,
"invalid subpostmaster invocation (--forkchild argument missing)");
591 child_kind = argv[1] + 12;
603 elog(
ERROR,
"unknown child kind %s", child_kind);
606 read_backend_variables(argv[2], &startup_data, &startup_data_len);
636 read_nondefault_variables();
680 extern struct bkend *ShmemBackendArray;
684 #define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
685 #define read_inheritable_socket(dest, src) (*(dest) = *(src))
687 static bool write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE child);
688 static bool write_inheritable_socket(InheritableSocket *
dest, SOCKET src,
690 static void read_inheritable_socket(SOCKET *
dest, InheritableSocket *src);
696 save_backend_variables(BackendParameters *param,
ClientSocket *client_sock,
698 HANDLE childProcess, pid_t childPid,
700 char *startup_data,
size_t startup_data_len)
703 memcpy(¶m->client_sock, client_sock,
sizeof(
ClientSocket));
706 if (!write_inheritable_socket(¶m->inh_sock,
723 param->ShmemBackendArray = ShmemBackendArray;
725 #ifndef HAVE_SPINLOCKS
750 param->PostmasterHandle = PostmasterHandle;
751 if (!write_duplicated_handle(¶m->initial_signal_pipe,
766 param->startup_data_len = startup_data_len;
767 memcpy(param->startup_data, startup_data, startup_data_len);
778 write_duplicated_handle(HANDLE *
dest, HANDLE src, HANDLE childProcess)
780 HANDLE hChild = INVALID_HANDLE_VALUE;
782 if (!DuplicateHandle(GetCurrentProcess(),
788 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
791 (
errmsg_internal(
"could not duplicate handle to be written to backend parameter file: error code %lu",
808 write_inheritable_socket(InheritableSocket *
dest, SOCKET src, pid_t childpid)
810 dest->origsocket = src;
814 if (WSADuplicateSocket(src, childpid, &
dest->wsainfo) != 0)
817 (
errmsg(
"could not duplicate socket %d for use in backend: error code %d",
818 (
int) src, WSAGetLastError())));
829 read_inheritable_socket(SOCKET *
dest, InheritableSocket *src)
836 *
dest = src->origsocket;
841 s = WSASocket(FROM_PROTOCOL_INFO,
847 if (s == INVALID_SOCKET)
849 write_stderr(
"could not create inherited socket: error code %d\n",
866 read_backend_variables(
char *
id,
char **startup_data,
size_t *startup_data_len)
868 BackendParameters param;
878 write_stderr(
"could not open backend variables file \"%s\": %m\n",
id);
882 if (fread(¶m,
sizeof(param), 1, fp) != 1)
884 write_stderr(
"could not read from backend variables file \"%s\": %m\n",
id);
889 *startup_data_len = param.startup_data_len;
890 if (param.startup_data_len > 0)
892 *startup_data =
palloc(*startup_data_len);
893 if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
895 write_stderr(
"could not read startup data from backend variables file \"%s\": %m\n",
901 *startup_data = NULL;
913 BackendParameters *paramp;
916 paramHandle = (HANDLE) _atoi64(
id);
918 paramHandle = (HANDLE) atol(
id);
920 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
923 write_stderr(
"could not map view of backend variables: error code %lu\n",
928 memcpy(¶m, paramp,
sizeof(BackendParameters));
931 *startup_data_len = param.startup_data_len;
932 if (param.startup_data_len > 0)
934 *startup_data =
palloc(paramp->startup_data_len);
935 memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
938 *startup_data = NULL;
940 if (!UnmapViewOfFile(paramp))
942 write_stderr(
"could not unmap view of backend variables: error code %lu\n",
947 if (!CloseHandle(paramHandle))
949 write_stderr(
"could not close handle to backend parameter variables: error code %lu\n",
955 restore_backend_variables(¶m);
960 restore_backend_variables(BackendParameters *param)
981 ShmemBackendArray = param->ShmemBackendArray;
983 #ifndef HAVE_SPINLOCKS
1008 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)
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)