Line data Source code
1 : /*-------------------------------------------------------------------------
2 : *
3 : * launch_backend.c
4 : * Functions for launching backends and other postmaster child
5 : * processes.
6 : *
7 : * On Unix systems, a new child process is launched with fork(). It inherits
8 : * all the global variables and data structures that had been initialized in
9 : * the postmaster. After forking, the child process closes the file
10 : * descriptors that are not needed in the child process, and sets up the
11 : * mechanism to detect death of the parent postmaster process, etc. After
12 : * that, it calls the right Main function depending on the kind of child
13 : * process.
14 : *
15 : * In EXEC_BACKEND mode, which is used on Windows but can be enabled on other
16 : * platforms for testing, the child process is launched by fork() + exec() (or
17 : * CreateProcess() on Windows). It does not inherit the state from the
18 : * postmaster, so it needs to re-attach to the shared memory, re-initialize
19 : * global variables, reload the config file etc. to get the process to the
20 : * same state as after fork() on a Unix system.
21 : *
22 : *
23 : * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
24 : * Portions Copyright (c) 1994, Regents of the University of California
25 : *
26 : * IDENTIFICATION
27 : * src/backend/postmaster/launch_backend.c
28 : *
29 : *-------------------------------------------------------------------------
30 : */
31 :
32 : #include "postgres.h"
33 :
34 : #include <unistd.h>
35 :
36 : #include "libpq/libpq-be.h"
37 : #include "miscadmin.h"
38 : #include "postmaster/autovacuum.h"
39 : #include "postmaster/bgworker_internals.h"
40 : #include "postmaster/bgwriter.h"
41 : #include "postmaster/fork_process.h"
42 : #include "postmaster/pgarch.h"
43 : #include "postmaster/postmaster.h"
44 : #include "postmaster/startup.h"
45 : #include "postmaster/syslogger.h"
46 : #include "postmaster/walsummarizer.h"
47 : #include "postmaster/walwriter.h"
48 : #include "replication/slotsync.h"
49 : #include "replication/walreceiver.h"
50 : #include "storage/dsm.h"
51 : #include "storage/io_worker.h"
52 : #include "storage/ipc.h"
53 : #include "storage/pg_shmem.h"
54 : #include "storage/shmem_internal.h"
55 : #include "tcop/backend_startup.h"
56 : #include "utils/memutils.h"
57 :
58 : #ifdef EXEC_BACKEND
59 : #include "nodes/queryjumble.h"
60 : #include "storage/pg_shmem.h"
61 : #include "storage/spin.h"
62 : #endif
63 :
64 :
65 : #ifdef EXEC_BACKEND
66 :
67 : #include "common/file_utils.h"
68 : #include "storage/fd.h"
69 : #include "storage/lwlock.h"
70 : #include "storage/pmsignal.h"
71 : #include "storage/proc.h"
72 : #include "storage/procsignal.h"
73 : #include "tcop/tcopprot.h"
74 : #include "utils/injection_point.h"
75 :
76 : /* Type for a socket that can be inherited to a client process */
77 : #ifdef WIN32
78 : typedef struct
79 : {
80 : SOCKET origsocket; /* Original socket value, or PGINVALID_SOCKET
81 : * if not a socket */
82 : WSAPROTOCOL_INFO wsainfo;
83 : } InheritableSocket;
84 : #else
85 : typedef int InheritableSocket;
86 : #endif
87 :
88 : /*
89 : * Structure contains all variables passed to exec:ed backends
90 : */
91 : typedef struct
92 : {
93 : char DataDir[MAXPGPATH];
94 : #ifndef WIN32
95 : unsigned long UsedShmemSegID;
96 : #else
97 : void *ShmemProtectiveRegion;
98 : HANDLE UsedShmemSegID;
99 : #endif
100 : void *UsedShmemSegAddr;
101 : #ifdef USE_INJECTION_POINTS
102 : struct InjectionPointsCtl *ActiveInjectionPoints;
103 : #endif
104 : PROC_HDR *ProcGlobal;
105 : PGPROC *AuxiliaryProcs;
106 : PGPROC *PreparedXactProcs;
107 : volatile PMSignalData *PMSignalState;
108 : ProcSignalHeader *ProcSignal;
109 : pid_t PostmasterPid;
110 : TimestampTz PgStartTime;
111 : TimestampTz PgReloadTime;
112 : pg_time_t first_syslogger_file_time;
113 : bool redirection_done;
114 : bool IsBinaryUpgrade;
115 : bool query_id_enabled;
116 : int max_safe_fds;
117 : int MaxBackends;
118 : int num_pmchild_slots;
119 : #ifdef WIN32
120 : HANDLE PostmasterHandle;
121 : HANDLE initial_signal_pipe;
122 : HANDLE syslogPipe[2];
123 : #else
124 : int postmaster_alive_fds[2];
125 : int syslogPipe[2];
126 : #endif
127 : char my_exec_path[MAXPGPATH];
128 : char pkglib_path[MAXPGPATH];
129 :
130 : int MyPMChildSlot;
131 :
132 : /*
133 : * These are only used by backend processes, but are here because passing
134 : * a socket needs some special handling on Windows. 'client_sock' is an
135 : * explicit argument to postmaster_child_launch, but is stored in
136 : * MyClientSocket in the child process.
137 : */
138 : ClientSocket client_sock;
139 : InheritableSocket inh_sock;
140 :
141 : /*
142 : * Extra startup data, content depends on the child process.
143 : */
144 : size_t startup_data_len;
145 : char startup_data[FLEXIBLE_ARRAY_MEMBER];
146 : } BackendParameters;
147 :
148 : #define SizeOfBackendParameters(startup_data_len) (offsetof(BackendParameters, startup_data) + startup_data_len)
149 :
150 : static void read_backend_variables(char *id, void **startup_data, size_t *startup_data_len);
151 : static void restore_backend_variables(BackendParameters *param);
152 :
153 : static bool save_backend_variables(BackendParameters *param, int child_slot,
154 : const ClientSocket *client_sock,
155 : #ifdef WIN32
156 : HANDLE childProcess, pid_t childPid,
157 : #endif
158 : const void *startup_data, size_t startup_data_len);
159 :
160 : static pid_t internal_forkexec(BackendType child_kind, int child_slot,
161 : const void *startup_data, size_t startup_data_len,
162 : const ClientSocket *client_sock);
163 :
164 : #endif /* EXEC_BACKEND */
165 :
166 : /*
167 : * Information needed to launch different kinds of child processes.
168 : */
169 : typedef struct
170 : {
171 : const char *name;
172 : void (*main_fn) (const void *startup_data, size_t startup_data_len);
173 : bool shmem_attach;
174 : } child_process_kind;
175 :
176 : static child_process_kind child_process_kinds[] = {
177 : #define PG_PROCTYPE(bktype, bkcategory, description, main_func, shmem_attach) \
178 : [bktype] = {description, main_func, shmem_attach},
179 : #include "postmaster/proctypelist.h"
180 : #undef PG_PROCTYPE
181 : };
182 :
183 : const char *
184 1197 : PostmasterChildName(BackendType child_type)
185 : {
186 1197 : return child_process_kinds[child_type].name;
187 : }
188 :
189 : /*
190 : * Start a new postmaster child process.
191 : *
192 : * The child process will be restored to roughly the same state whether
193 : * EXEC_BACKEND is used or not: it will be attached to shared memory if
194 : * appropriate, and fds and other resources that we've inherited from
195 : * postmaster that are not needed in a child process have been closed.
196 : *
197 : * 'child_slot' is the PMChildFlags array index reserved for the child
198 : * process. 'startup_data' is an optional contiguous chunk of data that is
199 : * passed to the child process.
200 : */
201 : pid_t
202 27861 : postmaster_child_launch(BackendType child_type, int child_slot,
203 : void *startup_data, size_t startup_data_len,
204 : const ClientSocket *client_sock)
205 : {
206 : pid_t pid;
207 :
208 : Assert(IsPostmasterEnvironment && !IsUnderPostmaster);
209 :
210 : /* Capture time Postmaster initiates process creation for logging */
211 27861 : if (IsExternalConnectionBackend(child_type))
212 14786 : ((BackendStartupData *) startup_data)->fork_started = GetCurrentTimestamp();
213 :
214 : #ifdef EXEC_BACKEND
215 : pid = internal_forkexec(child_type, child_slot,
216 : startup_data, startup_data_len, client_sock);
217 : /* the child process will arrive in SubPostmasterMain */
218 : #else /* !EXEC_BACKEND */
219 27861 : pid = fork_process();
220 52775 : if (pid == 0) /* child */
221 : {
222 24914 : MyBackendType = child_type;
223 :
224 : /* Capture and transfer timings that may be needed for logging */
225 24914 : if (IsExternalConnectionBackend(child_type))
226 : {
227 14610 : conn_timing.socket_create =
228 14610 : ((BackendStartupData *) startup_data)->socket_created;
229 14610 : conn_timing.fork_start =
230 14610 : ((BackendStartupData *) startup_data)->fork_started;
231 14610 : conn_timing.fork_end = GetCurrentTimestamp();
232 : }
233 :
234 : /* Close the postmaster's sockets */
235 24914 : ClosePostmasterPorts(child_type == B_LOGGER);
236 :
237 : /* Detangle from postmaster */
238 24914 : InitPostmasterChild();
239 :
240 : /* Detach shared memory if not needed. */
241 24914 : if (!child_process_kinds[child_type].shmem_attach)
242 : {
243 1 : dsm_detach_all();
244 1 : PGSharedMemoryDetach();
245 : }
246 :
247 : /*
248 : * Enter the Main function with TopMemoryContext. The startup data is
249 : * allocated in PostmasterContext, so we cannot release it here yet.
250 : * The Main function will do it after it's done handling the startup
251 : * data.
252 : */
253 24914 : MemoryContextSwitchTo(TopMemoryContext);
254 :
255 24914 : MyPMChildSlot = child_slot;
256 24914 : if (client_sock)
257 : {
258 14835 : MyClientSocket = palloc_object(ClientSocket);
259 14835 : memcpy(MyClientSocket, client_sock, sizeof(ClientSocket));
260 : }
261 :
262 : /*
263 : * Run the appropriate Main function
264 : */
265 24914 : child_process_kinds[child_type].main_fn(startup_data, startup_data_len);
266 0 : pg_unreachable(); /* main_fn never returns */
267 : }
268 : #endif /* EXEC_BACKEND */
269 27861 : return pid;
270 : }
271 :
272 : #ifdef EXEC_BACKEND
273 : #ifndef WIN32
274 :
275 : /*
276 : * internal_forkexec non-win32 implementation
277 : *
278 : * - writes out backend variables to the parameter file
279 : * - fork():s, and then exec():s the child process
280 : */
281 : static pid_t
282 : internal_forkexec(BackendType child_kind, int child_slot,
283 : const void *startup_data, size_t startup_data_len, const ClientSocket *client_sock)
284 : {
285 : static unsigned long tmpBackendFileNum = 0;
286 : pid_t pid;
287 : char tmpfilename[MAXPGPATH];
288 : size_t paramsz;
289 : BackendParameters *param;
290 : FILE *fp;
291 : char *argv[4];
292 : char forkav[MAXPGPATH];
293 :
294 : /*
295 : * Use palloc0 to make sure padding bytes are initialized, to prevent
296 : * Valgrind from complaining about writing uninitialized bytes to the
297 : * file. This isn't performance critical, and the win32 implementation
298 : * initializes the padding bytes to zeros, so do it even when not using
299 : * Valgrind.
300 : */
301 : paramsz = SizeOfBackendParameters(startup_data_len);
302 : param = palloc0(paramsz);
303 : if (!save_backend_variables(param, child_slot, client_sock, startup_data, startup_data_len))
304 : {
305 : pfree(param);
306 : return -1; /* log made by save_backend_variables */
307 : }
308 :
309 : /* Calculate name for temp file */
310 : snprintf(tmpfilename, MAXPGPATH, "%s/%s.backend_var.%d.%lu",
311 : PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
312 : MyProcPid, ++tmpBackendFileNum);
313 :
314 : /* Open file */
315 : fp = AllocateFile(tmpfilename, PG_BINARY_W);
316 : if (!fp)
317 : {
318 : /*
319 : * As in OpenTemporaryFileInTablespace, try to make the temp-file
320 : * directory, ignoring errors.
321 : */
322 : (void) MakePGDirectory(PG_TEMP_FILES_DIR);
323 :
324 : fp = AllocateFile(tmpfilename, PG_BINARY_W);
325 : if (!fp)
326 : {
327 : ereport(LOG,
328 : (errcode_for_file_access(),
329 : errmsg("could not create file \"%s\": %m",
330 : tmpfilename)));
331 : pfree(param);
332 : return -1;
333 : }
334 : }
335 :
336 : if (fwrite(param, paramsz, 1, fp) != 1)
337 : {
338 : ereport(LOG,
339 : (errcode_for_file_access(),
340 : errmsg("could not write to file \"%s\": %m", tmpfilename)));
341 : FreeFile(fp);
342 : pfree(param);
343 : return -1;
344 : }
345 : pfree(param);
346 :
347 : /* Release file */
348 : if (FreeFile(fp))
349 : {
350 : ereport(LOG,
351 : (errcode_for_file_access(),
352 : errmsg("could not write to file \"%s\": %m", tmpfilename)));
353 : return -1;
354 : }
355 :
356 : /* set up argv properly */
357 : argv[0] = "postgres";
358 : snprintf(forkav, MAXPGPATH, "--forkchild=%d", (int) child_kind);
359 : argv[1] = forkav;
360 : /* Insert temp file name after --forkchild argument */
361 : argv[2] = tmpfilename;
362 : argv[3] = NULL;
363 :
364 : /* Fire off execv in child */
365 : if ((pid = fork_process()) == 0)
366 : {
367 : if (execv(postgres_exec_path, argv) < 0)
368 : {
369 : ereport(LOG,
370 : (errmsg("could not execute server process \"%s\": %m",
371 : postgres_exec_path)));
372 : /* We're already in the child process here, can't return */
373 : exit(1);
374 : }
375 : }
376 :
377 : return pid; /* Parent returns pid, or -1 on fork failure */
378 : }
379 : #else /* WIN32 */
380 :
381 : /*
382 : * internal_forkexec win32 implementation
383 : *
384 : * - starts backend using CreateProcess(), in suspended state
385 : * - writes out backend variables to the parameter file
386 : * - during this, duplicates handles and sockets required for
387 : * inheritance into the new process
388 : * - resumes execution of the new process once the backend parameter
389 : * file is complete.
390 : */
391 : static pid_t
392 : internal_forkexec(BackendType child_kind, int child_slot,
393 : const void *startup_data, size_t startup_data_len, const ClientSocket *client_sock)
394 : {
395 : int retry_count = 0;
396 : STARTUPINFO si;
397 : PROCESS_INFORMATION pi;
398 : char cmdLine[MAXPGPATH * 2];
399 : HANDLE paramHandle;
400 : BackendParameters *param;
401 : SECURITY_ATTRIBUTES sa;
402 : size_t paramsz;
403 : char paramHandleStr[32];
404 : int l;
405 :
406 : paramsz = SizeOfBackendParameters(startup_data_len);
407 :
408 : /* Resume here if we need to retry */
409 : retry:
410 :
411 : /* Set up shared memory for parameter passing */
412 : ZeroMemory(&sa, sizeof(sa));
413 : sa.nLength = sizeof(sa);
414 : sa.bInheritHandle = TRUE;
415 : paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
416 : &sa,
417 : PAGE_READWRITE,
418 : 0,
419 : paramsz,
420 : NULL);
421 : if (paramHandle == INVALID_HANDLE_VALUE)
422 : {
423 : ereport(LOG,
424 : (errmsg("could not create backend parameter file mapping: error code %lu",
425 : GetLastError())));
426 : return -1;
427 : }
428 : param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, paramsz);
429 : if (!param)
430 : {
431 : ereport(LOG,
432 : (errmsg("could not map backend parameter memory: error code %lu",
433 : GetLastError())));
434 : CloseHandle(paramHandle);
435 : return -1;
436 : }
437 :
438 : /* Format the cmd line */
439 : #ifdef _WIN64
440 : sprintf(paramHandleStr, "%llu", (LONG_PTR) paramHandle);
441 : #else
442 : sprintf(paramHandleStr, "%lu", (DWORD) paramHandle);
443 : #endif
444 : l = snprintf(cmdLine, sizeof(cmdLine) - 1, "\"%s\" --forkchild=%d %s",
445 : postgres_exec_path, (int) child_kind, paramHandleStr);
446 : if (l >= sizeof(cmdLine))
447 : {
448 : ereport(LOG,
449 : (errmsg("subprocess command line too long")));
450 : UnmapViewOfFile(param);
451 : CloseHandle(paramHandle);
452 : return -1;
453 : }
454 :
455 : memset(&pi, 0, sizeof(pi));
456 : memset(&si, 0, sizeof(si));
457 : si.cb = sizeof(si);
458 :
459 : /*
460 : * Create the subprocess in a suspended state. This will be resumed later,
461 : * once we have written out the parameter file.
462 : */
463 : if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
464 : NULL, NULL, &si, &pi))
465 : {
466 : ereport(LOG,
467 : (errmsg("CreateProcess() call failed: %m (error code %lu)",
468 : GetLastError())));
469 : UnmapViewOfFile(param);
470 : CloseHandle(paramHandle);
471 : return -1;
472 : }
473 :
474 : if (!save_backend_variables(param, child_slot, client_sock,
475 : pi.hProcess, pi.dwProcessId,
476 : startup_data, startup_data_len))
477 : {
478 : /*
479 : * log made by save_backend_variables, but we have to clean up the
480 : * mess with the half-started process
481 : */
482 : if (!TerminateProcess(pi.hProcess, 255))
483 : ereport(LOG,
484 : (errmsg_internal("could not terminate unstarted process: error code %lu",
485 : GetLastError())));
486 : CloseHandle(pi.hProcess);
487 : CloseHandle(pi.hThread);
488 : UnmapViewOfFile(param);
489 : CloseHandle(paramHandle);
490 : return -1; /* log made by save_backend_variables */
491 : }
492 :
493 : /* Drop the parameter shared memory that is now inherited to the backend */
494 : if (!UnmapViewOfFile(param))
495 : ereport(LOG,
496 : (errmsg("could not unmap view of backend parameter file: error code %lu",
497 : GetLastError())));
498 : if (!CloseHandle(paramHandle))
499 : ereport(LOG,
500 : (errmsg("could not close handle to backend parameter file: error code %lu",
501 : GetLastError())));
502 :
503 : /*
504 : * Reserve the memory region used by our main shared memory segment before
505 : * we resume the child process. Normally this should succeed, but if ASLR
506 : * is active then it might sometimes fail due to the stack or heap having
507 : * gotten mapped into that range. In that case, just terminate the
508 : * process and retry.
509 : */
510 : if (!pgwin32_ReserveSharedMemoryRegion(pi.hProcess))
511 : {
512 : /* pgwin32_ReserveSharedMemoryRegion already made a log entry */
513 : if (!TerminateProcess(pi.hProcess, 255))
514 : ereport(LOG,
515 : (errmsg_internal("could not terminate process that failed to reserve memory: error code %lu",
516 : GetLastError())));
517 : CloseHandle(pi.hProcess);
518 : CloseHandle(pi.hThread);
519 : if (++retry_count < 100)
520 : goto retry;
521 : ereport(LOG,
522 : (errmsg("giving up after too many tries to reserve shared memory"),
523 : errhint("This might be caused by ASLR or antivirus software.")));
524 : return -1;
525 : }
526 :
527 : /*
528 : * Now that the backend variables are written out, we start the child
529 : * thread so it can start initializing while we set up the rest of the
530 : * parent state.
531 : */
532 : if (ResumeThread(pi.hThread) == -1)
533 : {
534 : if (!TerminateProcess(pi.hProcess, 255))
535 : {
536 : ereport(LOG,
537 : (errmsg_internal("could not terminate unstartable process: error code %lu",
538 : GetLastError())));
539 : CloseHandle(pi.hProcess);
540 : CloseHandle(pi.hThread);
541 : return -1;
542 : }
543 : CloseHandle(pi.hProcess);
544 : CloseHandle(pi.hThread);
545 : ereport(LOG,
546 : (errmsg_internal("could not resume thread of unstarted process: error code %lu",
547 : GetLastError())));
548 : return -1;
549 : }
550 :
551 : /* Set up notification when the child process dies */
552 : pgwin32_register_deadchild_callback(pi.hProcess, pi.dwProcessId);
553 :
554 : /* Don't close pi.hProcess, it's owned by the deadchild callback now */
555 :
556 : CloseHandle(pi.hThread);
557 :
558 : return pi.dwProcessId;
559 : }
560 : #endif /* WIN32 */
561 :
562 : /*
563 : * SubPostmasterMain -- Get the fork/exec'd process into a state equivalent
564 : * to what it would be if we'd simply forked on Unix, and then
565 : * dispatch to the appropriate place.
566 : *
567 : * The first two command line arguments are expected to be "--forkchild=<kind>",
568 : * where <kind> indicates which process type we are to become, and
569 : * the name of a variables file that we can read to load data that would
570 : * have been inherited by fork() on Unix.
571 : */
572 : void
573 : SubPostmasterMain(int argc, char *argv[])
574 : {
575 : void *startup_data;
576 : size_t startup_data_len;
577 : char *child_kind;
578 : BackendType child_type;
579 : TimestampTz fork_end;
580 :
581 : /* In EXEC_BACKEND case we will not have inherited these settings */
582 : IsPostmasterEnvironment = true;
583 : whereToSendOutput = DestNone;
584 :
585 : /*
586 : * Capture the end of process creation for logging. We don't include the
587 : * time spent copying data from shared memory and setting up the backend.
588 : */
589 : fork_end = GetCurrentTimestamp();
590 :
591 : /* Setup essential subsystems (to ensure elog() behaves sanely) */
592 : InitializeGUCOptions();
593 :
594 : /* Check we got appropriate args */
595 : if (argc != 3)
596 : elog(FATAL, "invalid subpostmaster invocation");
597 :
598 : /*
599 : * Parse the --forkchild argument to find our process type. We rely with
600 : * malice aforethought on atoi returning 0 (B_INVALID) on error.
601 : */
602 : if (strncmp(argv[1], "--forkchild=", 12) != 0)
603 : elog(FATAL, "invalid subpostmaster invocation (--forkchild argument missing)");
604 : child_kind = argv[1] + 12;
605 : child_type = (BackendType) atoi(child_kind);
606 : if (child_type <= B_INVALID || child_type > BACKEND_NUM_TYPES - 1)
607 : elog(ERROR, "unknown child kind %s", child_kind);
608 : MyBackendType = child_type;
609 :
610 : /* Read in the variables file */
611 : read_backend_variables(argv[2], &startup_data, &startup_data_len);
612 :
613 : /* Close the postmaster's sockets (as soon as we know them) */
614 : ClosePostmasterPorts(child_type == B_LOGGER);
615 :
616 : /* Setup as postmaster child */
617 : InitPostmasterChild();
618 :
619 : /*
620 : * If appropriate, physically re-attach to shared memory segment. We want
621 : * to do this before going any further to ensure that we can attach at the
622 : * same address the postmaster used. On the other hand, if we choose not
623 : * to re-attach, we may have other cleanup to do.
624 : *
625 : * If testing EXEC_BACKEND on Linux, you should run this as root before
626 : * starting the postmaster:
627 : *
628 : * sysctl -w kernel.randomize_va_space=0
629 : *
630 : * This prevents using randomized stack and code addresses that cause the
631 : * child process's memory map to be different from the parent's, making it
632 : * sometimes impossible to attach to shared memory at the desired address.
633 : * Return the setting to its old value (usually '1' or '2') when finished.
634 : */
635 : if (child_process_kinds[child_type].shmem_attach)
636 : PGSharedMemoryReAttach();
637 : else
638 : PGSharedMemoryNoReAttach();
639 :
640 : /* Read in remaining GUC variables */
641 : read_nondefault_variables();
642 :
643 : /* Capture and transfer timings that may be needed for log_connections */
644 : if (IsExternalConnectionBackend(child_type))
645 : {
646 : conn_timing.socket_create =
647 : ((BackendStartupData *) startup_data)->socket_created;
648 : conn_timing.fork_start =
649 : ((BackendStartupData *) startup_data)->fork_started;
650 : conn_timing.fork_end = fork_end;
651 : }
652 :
653 : /*
654 : * Check that the data directory looks valid, which will also check the
655 : * privileges on the data directory and update our umask and file/group
656 : * variables for creating files later. Note: this should really be done
657 : * before we create any files or directories.
658 : */
659 : checkDataDir();
660 :
661 : /*
662 : * (re-)read control file, as it contains config. The postmaster will
663 : * already have read this, but this process doesn't know about that.
664 : */
665 : LocalProcessControlFile(false);
666 :
667 : RegisterBuiltinShmemCallbacks();
668 :
669 : /*
670 : * Reload any libraries that were preloaded by the postmaster. Since we
671 : * exec'd this process, those libraries didn't come along with us; but we
672 : * should load them into all child processes to be consistent with the
673 : * non-EXEC_BACKEND behavior.
674 : */
675 : process_shared_preload_libraries();
676 :
677 : /* Restore basic shared memory pointers */
678 : if (UsedShmemSegAddr != NULL)
679 : {
680 : InitShmemAllocator(UsedShmemSegAddr);
681 : ShmemCallRequestCallbacks();
682 : }
683 :
684 : /*
685 : * Run the appropriate Main function
686 : */
687 : child_process_kinds[child_type].main_fn(startup_data, startup_data_len);
688 : pg_unreachable(); /* main_fn never returns */
689 : }
690 :
691 : #ifndef WIN32
692 : #define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
693 : #define read_inheritable_socket(dest, src) (*(dest) = *(src))
694 : #else
695 : static bool write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE child);
696 : static bool write_inheritable_socket(InheritableSocket *dest, SOCKET src,
697 : pid_t childPid);
698 : static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
699 : #endif
700 :
701 :
702 : /* Save critical backend variables into the BackendParameters struct */
703 : static bool
704 : save_backend_variables(BackendParameters *param,
705 : int child_slot, const ClientSocket *client_sock,
706 : #ifdef WIN32
707 : HANDLE childProcess, pid_t childPid,
708 : #endif
709 : const void *startup_data, size_t startup_data_len)
710 : {
711 : if (client_sock)
712 : memcpy(¶m->client_sock, client_sock, sizeof(ClientSocket));
713 : else
714 : memset(¶m->client_sock, 0, sizeof(ClientSocket));
715 : if (!write_inheritable_socket(¶m->inh_sock,
716 : client_sock ? client_sock->sock : PGINVALID_SOCKET,
717 : childPid))
718 : return false;
719 :
720 : strlcpy(param->DataDir, DataDir, MAXPGPATH);
721 :
722 : param->MyPMChildSlot = child_slot;
723 :
724 : #ifdef WIN32
725 : param->ShmemProtectiveRegion = ShmemProtectiveRegion;
726 : #endif
727 : param->UsedShmemSegID = UsedShmemSegID;
728 : param->UsedShmemSegAddr = UsedShmemSegAddr;
729 :
730 : #ifdef USE_INJECTION_POINTS
731 : param->ActiveInjectionPoints = ActiveInjectionPoints;
732 : #endif
733 :
734 : param->ProcGlobal = ProcGlobal;
735 : param->AuxiliaryProcs = AuxiliaryProcs;
736 : param->PreparedXactProcs = PreparedXactProcs;
737 : param->PMSignalState = PMSignalState;
738 : param->ProcSignal = ProcSignal;
739 :
740 : param->PostmasterPid = PostmasterPid;
741 : param->PgStartTime = PgStartTime;
742 : param->PgReloadTime = PgReloadTime;
743 : param->first_syslogger_file_time = first_syslogger_file_time;
744 :
745 : param->redirection_done = redirection_done;
746 : param->IsBinaryUpgrade = IsBinaryUpgrade;
747 : param->query_id_enabled = query_id_enabled;
748 : param->max_safe_fds = max_safe_fds;
749 :
750 : param->MaxBackends = MaxBackends;
751 : param->num_pmchild_slots = num_pmchild_slots;
752 :
753 : #ifdef WIN32
754 : param->PostmasterHandle = PostmasterHandle;
755 : if (!write_duplicated_handle(¶m->initial_signal_pipe,
756 : pgwin32_create_signal_listener(childPid),
757 : childProcess))
758 : return false;
759 : #else
760 : memcpy(¶m->postmaster_alive_fds, &postmaster_alive_fds,
761 : sizeof(postmaster_alive_fds));
762 : #endif
763 :
764 : memcpy(¶m->syslogPipe, &syslogPipe, sizeof(syslogPipe));
765 :
766 : strlcpy(param->my_exec_path, my_exec_path, MAXPGPATH);
767 :
768 : strlcpy(param->pkglib_path, pkglib_path, MAXPGPATH);
769 :
770 : param->startup_data_len = startup_data_len;
771 : if (startup_data_len > 0)
772 : memcpy(param->startup_data, startup_data, startup_data_len);
773 :
774 : return true;
775 : }
776 :
777 : #ifdef WIN32
778 : /*
779 : * Duplicate a handle for usage in a child process, and write the child
780 : * process instance of the handle to the parameter file.
781 : */
782 : static bool
783 : write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE childProcess)
784 : {
785 : HANDLE hChild = INVALID_HANDLE_VALUE;
786 :
787 : if (!DuplicateHandle(GetCurrentProcess(),
788 : src,
789 : childProcess,
790 : &hChild,
791 : 0,
792 : TRUE,
793 : DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
794 : {
795 : ereport(LOG,
796 : (errmsg_internal("could not duplicate handle to be written to backend parameter file: error code %lu",
797 : GetLastError())));
798 : return false;
799 : }
800 :
801 : *dest = hChild;
802 : return true;
803 : }
804 :
805 : /*
806 : * Duplicate a socket for usage in a child process, and write the resulting
807 : * structure to the parameter file.
808 : * This is required because a number of LSPs (Layered Service Providers) very
809 : * common on Windows (antivirus, firewalls, download managers etc) break
810 : * straight socket inheritance.
811 : */
812 : static bool
813 : write_inheritable_socket(InheritableSocket *dest, SOCKET src, pid_t childpid)
814 : {
815 : dest->origsocket = src;
816 : if (src != 0 && src != PGINVALID_SOCKET)
817 : {
818 : /* Actual socket */
819 : if (WSADuplicateSocket(src, childpid, &dest->wsainfo) != 0)
820 : {
821 : ereport(LOG,
822 : (errmsg("could not duplicate socket %d for use in backend: error code %d",
823 : (int) src, WSAGetLastError())));
824 : return false;
825 : }
826 : }
827 : return true;
828 : }
829 :
830 : /*
831 : * Read a duplicate socket structure back, and get the socket descriptor.
832 : */
833 : static void
834 : read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
835 : {
836 : SOCKET s;
837 :
838 : if (src->origsocket == PGINVALID_SOCKET || src->origsocket == 0)
839 : {
840 : /* Not a real socket! */
841 : *dest = src->origsocket;
842 : }
843 : else
844 : {
845 : /* Actual socket, so create from structure */
846 : s = WSASocket(FROM_PROTOCOL_INFO,
847 : FROM_PROTOCOL_INFO,
848 : FROM_PROTOCOL_INFO,
849 : &src->wsainfo,
850 : 0,
851 : 0);
852 : if (s == INVALID_SOCKET)
853 : {
854 : write_stderr("could not create inherited socket: error code %d\n",
855 : WSAGetLastError());
856 : exit(1);
857 : }
858 : *dest = s;
859 :
860 : /*
861 : * To make sure we don't get two references to the same socket, close
862 : * the original one. (This would happen when inheritance actually
863 : * works..
864 : */
865 : closesocket(src->origsocket);
866 : }
867 : }
868 : #endif
869 :
870 : static void
871 : read_backend_variables(char *id, void **startup_data, size_t *startup_data_len)
872 : {
873 : BackendParameters param;
874 :
875 : #ifndef WIN32
876 : /* Non-win32 implementation reads from file */
877 : FILE *fp;
878 :
879 : /* Open file */
880 : fp = AllocateFile(id, PG_BINARY_R);
881 : if (!fp)
882 : {
883 : write_stderr("could not open backend variables file \"%s\": %m\n", id);
884 : exit(1);
885 : }
886 :
887 : if (fread(¶m, sizeof(param), 1, fp) != 1)
888 : {
889 : write_stderr("could not read from backend variables file \"%s\": %m\n", id);
890 : exit(1);
891 : }
892 :
893 : /* read startup data */
894 : *startup_data_len = param.startup_data_len;
895 : if (param.startup_data_len > 0)
896 : {
897 : *startup_data = palloc(*startup_data_len);
898 : if (fread(*startup_data, *startup_data_len, 1, fp) != 1)
899 : {
900 : write_stderr("could not read startup data from backend variables file \"%s\": %m\n",
901 : id);
902 : exit(1);
903 : }
904 : }
905 : else
906 : *startup_data = NULL;
907 :
908 : /* Release file */
909 : FreeFile(fp);
910 : if (unlink(id) != 0)
911 : {
912 : write_stderr("could not remove file \"%s\": %m\n", id);
913 : exit(1);
914 : }
915 : #else
916 : /* Win32 version uses mapped file */
917 : HANDLE paramHandle;
918 : BackendParameters *paramp;
919 :
920 : #ifdef _WIN64
921 : paramHandle = (HANDLE) _atoi64(id);
922 : #else
923 : paramHandle = (HANDLE) atol(id);
924 : #endif
925 : paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
926 : if (!paramp)
927 : {
928 : write_stderr("could not map view of backend variables: error code %lu\n",
929 : GetLastError());
930 : exit(1);
931 : }
932 :
933 : memcpy(¶m, paramp, sizeof(BackendParameters));
934 :
935 : /* read startup data */
936 : *startup_data_len = param.startup_data_len;
937 : if (param.startup_data_len > 0)
938 : {
939 : *startup_data = palloc(paramp->startup_data_len);
940 : memcpy(*startup_data, paramp->startup_data, param.startup_data_len);
941 : }
942 : else
943 : *startup_data = NULL;
944 :
945 : if (!UnmapViewOfFile(paramp))
946 : {
947 : write_stderr("could not unmap view of backend variables: error code %lu\n",
948 : GetLastError());
949 : exit(1);
950 : }
951 :
952 : if (!CloseHandle(paramHandle))
953 : {
954 : write_stderr("could not close handle to backend parameter variables: error code %lu\n",
955 : GetLastError());
956 : exit(1);
957 : }
958 : #endif
959 :
960 : restore_backend_variables(¶m);
961 : }
962 :
963 : /* Restore critical backend variables from the BackendParameters struct */
964 : static void
965 : restore_backend_variables(BackendParameters *param)
966 : {
967 : if (param->client_sock.sock != PGINVALID_SOCKET)
968 : {
969 : MyClientSocket = MemoryContextAlloc(TopMemoryContext, sizeof(ClientSocket));
970 : memcpy(MyClientSocket, ¶m->client_sock, sizeof(ClientSocket));
971 : read_inheritable_socket(&MyClientSocket->sock, ¶m->inh_sock);
972 : }
973 :
974 : SetDataDir(param->DataDir);
975 :
976 : MyPMChildSlot = param->MyPMChildSlot;
977 :
978 : #ifdef WIN32
979 : ShmemProtectiveRegion = param->ShmemProtectiveRegion;
980 : #endif
981 : UsedShmemSegID = param->UsedShmemSegID;
982 : UsedShmemSegAddr = param->UsedShmemSegAddr;
983 :
984 : #ifdef USE_INJECTION_POINTS
985 : ActiveInjectionPoints = param->ActiveInjectionPoints;
986 : #endif
987 :
988 : ProcGlobal = param->ProcGlobal;
989 : AuxiliaryProcs = param->AuxiliaryProcs;
990 : PreparedXactProcs = param->PreparedXactProcs;
991 : PMSignalState = param->PMSignalState;
992 : ProcSignal = param->ProcSignal;
993 :
994 : PostmasterPid = param->PostmasterPid;
995 : PgStartTime = param->PgStartTime;
996 : PgReloadTime = param->PgReloadTime;
997 : first_syslogger_file_time = param->first_syslogger_file_time;
998 :
999 : redirection_done = param->redirection_done;
1000 : IsBinaryUpgrade = param->IsBinaryUpgrade;
1001 : query_id_enabled = param->query_id_enabled;
1002 : max_safe_fds = param->max_safe_fds;
1003 :
1004 : MaxBackends = param->MaxBackends;
1005 : num_pmchild_slots = param->num_pmchild_slots;
1006 :
1007 : #ifdef WIN32
1008 : PostmasterHandle = param->PostmasterHandle;
1009 : pgwin32_initial_signal_pipe = param->initial_signal_pipe;
1010 : #else
1011 : memcpy(&postmaster_alive_fds, ¶m->postmaster_alive_fds,
1012 : sizeof(postmaster_alive_fds));
1013 : #endif
1014 :
1015 : memcpy(&syslogPipe, ¶m->syslogPipe, sizeof(syslogPipe));
1016 :
1017 : strlcpy(my_exec_path, param->my_exec_path, MAXPGPATH);
1018 :
1019 : strlcpy(pkglib_path, param->pkglib_path, MAXPGPATH);
1020 :
1021 : /*
1022 : * We need to restore fd.c's counts of externally-opened FDs; to avoid
1023 : * confusion, be sure to do this after restoring max_safe_fds. (Note:
1024 : * BackendInitialize will handle this for (*client_sock)->sock.)
1025 : */
1026 : #ifndef WIN32
1027 : if (postmaster_alive_fds[0] >= 0)
1028 : ReserveExternalFD();
1029 : if (postmaster_alive_fds[1] >= 0)
1030 : ReserveExternalFD();
1031 : #endif
1032 : }
1033 :
1034 : #endif /* EXEC_BACKEND */
|