Line data Source code
1 : /* 2 : * fork_process.c 3 : * A simple wrapper on top of fork(). This does not handle the 4 : * EXEC_BACKEND case; it might be extended to do so, but it would be 5 : * considerably more complex. 6 : * 7 : * Copyright (c) 1996-2025, PostgreSQL Global Development Group 8 : * 9 : * IDENTIFICATION 10 : * src/backend/postmaster/fork_process.c 11 : */ 12 : #include "postgres.h" 13 : 14 : #include <fcntl.h> 15 : #include <signal.h> 16 : #include <time.h> 17 : #include <sys/stat.h> 18 : #include <sys/time.h> 19 : #include <unistd.h> 20 : 21 : #include "libpq/pqsignal.h" 22 : #include "miscadmin.h" 23 : #include "postmaster/fork_process.h" 24 : 25 : #ifndef WIN32 26 : /* 27 : * Wrapper for fork(). Return values are the same as those for fork(): 28 : * -1 if the fork failed, 0 in the child process, and the PID of the 29 : * child in the parent process. Signals are blocked while forking, so 30 : * the child must unblock. 31 : */ 32 : pid_t 33 40950 : fork_process(void) 34 : { 35 : pid_t result; 36 : const char *oomfilename; 37 : sigset_t save_mask; 38 : 39 : #ifdef LINUX_PROFILE 40 : struct itimerval prof_itimer; 41 : #endif 42 : 43 : /* 44 : * Flush stdio channels just before fork, to avoid double-output problems. 45 : */ 46 40950 : fflush(NULL); 47 : 48 : #ifdef LINUX_PROFILE 49 : 50 : /* 51 : * Linux's fork() resets the profiling timer in the child process. If we 52 : * want to profile child processes then we need to save and restore the 53 : * timer setting. This is a waste of time if not profiling, however, so 54 : * only do it if commanded by specific -DLINUX_PROFILE switch. 55 : */ 56 : getitimer(ITIMER_PROF, &prof_itimer); 57 : #endif 58 : 59 : /* 60 : * We start postmaster children with signals blocked. This allows them to 61 : * install their own handlers before unblocking, to avoid races where they 62 : * might run the postmaster's handler and miss an important control 63 : * signal. With more analysis this could potentially be relaxed. 64 : */ 65 40950 : sigprocmask(SIG_SETMASK, &BlockSig, &save_mask); 66 40950 : result = fork(); 67 78328 : if (result == 0) 68 : { 69 : /* fork succeeded, in child */ 70 37384 : MyProcPid = getpid(); 71 : #ifdef LINUX_PROFILE 72 : setitimer(ITIMER_PROF, &prof_itimer, NULL); 73 : #endif 74 : 75 : /* 76 : * By default, Linux tends to kill the postmaster in out-of-memory 77 : * situations, because it blames the postmaster for the sum of child 78 : * process sizes *including shared memory*. (This is unbelievably 79 : * stupid, but the kernel hackers seem uninterested in improving it.) 80 : * Therefore it's often a good idea to protect the postmaster by 81 : * setting its OOM score adjustment negative (which has to be done in 82 : * a root-owned startup script). Since the adjustment is inherited by 83 : * child processes, this would ordinarily mean that all the 84 : * postmaster's children are equally protected against OOM kill, which 85 : * is not such a good idea. So we provide this code to allow the 86 : * children to change their OOM score adjustments again. Both the 87 : * file name to write to and the value to write are controlled by 88 : * environment variables, which can be set by the same startup script 89 : * that did the original adjustment. 90 : */ 91 37384 : oomfilename = getenv("PG_OOM_ADJUST_FILE"); 92 : 93 37384 : if (oomfilename != NULL) 94 : { 95 : /* 96 : * Use open() not stdio, to ensure we control the open flags. Some 97 : * Linux security environments reject anything but O_WRONLY. 98 : */ 99 0 : int fd = open(oomfilename, O_WRONLY, 0); 100 : 101 : /* We ignore all errors */ 102 0 : if (fd >= 0) 103 : { 104 0 : const char *oomvalue = getenv("PG_OOM_ADJUST_VALUE"); 105 : int rc; 106 : 107 0 : if (oomvalue == NULL) /* supply a useful default */ 108 0 : oomvalue = "0"; 109 : 110 0 : rc = write(fd, oomvalue, strlen(oomvalue)); 111 : (void) rc; 112 0 : close(fd); 113 : } 114 : } 115 : 116 : /* do post-fork initialization for random number generation */ 117 37384 : pg_strong_random_init(); 118 : } 119 : else 120 : { 121 : /* in parent, restore signal mask */ 122 40944 : sigprocmask(SIG_SETMASK, &save_mask, NULL); 123 : } 124 : 125 78328 : return result; 126 : } 127 : 128 : #endif /* ! WIN32 */