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-2022, 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 <time.h> 16 : #include <sys/stat.h> 17 : #include <sys/time.h> 18 : #include <unistd.h> 19 : 20 : #include "postmaster/fork_process.h" 21 : 22 : #ifndef WIN32 23 : /* 24 : * Wrapper for fork(). Return values are the same as those for fork(): 25 : * -1 if the fork failed, 0 in the child process, and the PID of the 26 : * child in the parent process. 27 : */ 28 : pid_t 29 24988 : fork_process(void) 30 : { 31 : pid_t result; 32 : const char *oomfilename; 33 : 34 : #ifdef LINUX_PROFILE 35 : struct itimerval prof_itimer; 36 : #endif 37 : 38 : /* 39 : * Flush stdio channels just before fork, to avoid double-output problems. 40 : * Ideally we'd use fflush(NULL) here, but there are still a few non-ANSI 41 : * stdio libraries out there (like SunOS 4.1.x) that coredump if we do. 42 : * Presently stdout and stderr are the only stdio output channels used by 43 : * the postmaster, so fflush'ing them should be sufficient. 44 : */ 45 24988 : fflush(stdout); 46 24988 : fflush(stderr); 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 24988 : result = fork(); 60 47724 : if (result == 0) 61 : { 62 : /* fork succeeded, in child */ 63 : #ifdef LINUX_PROFILE 64 : setitimer(ITIMER_PROF, &prof_itimer, NULL); 65 : #endif 66 : 67 : /* 68 : * By default, Linux tends to kill the postmaster in out-of-memory 69 : * situations, because it blames the postmaster for the sum of child 70 : * process sizes *including shared memory*. (This is unbelievably 71 : * stupid, but the kernel hackers seem uninterested in improving it.) 72 : * Therefore it's often a good idea to protect the postmaster by 73 : * setting its OOM score adjustment negative (which has to be done in 74 : * a root-owned startup script). Since the adjustment is inherited by 75 : * child processes, this would ordinarily mean that all the 76 : * postmaster's children are equally protected against OOM kill, which 77 : * is not such a good idea. So we provide this code to allow the 78 : * children to change their OOM score adjustments again. Both the 79 : * file name to write to and the value to write are controlled by 80 : * environment variables, which can be set by the same startup script 81 : * that did the original adjustment. 82 : */ 83 22742 : oomfilename = getenv("PG_OOM_ADJUST_FILE"); 84 : 85 22742 : if (oomfilename != NULL) 86 : { 87 : /* 88 : * Use open() not stdio, to ensure we control the open flags. Some 89 : * Linux security environments reject anything but O_WRONLY. 90 : */ 91 0 : int fd = open(oomfilename, O_WRONLY, 0); 92 : 93 : /* We ignore all errors */ 94 0 : if (fd >= 0) 95 : { 96 0 : const char *oomvalue = getenv("PG_OOM_ADJUST_VALUE"); 97 : int rc; 98 : 99 0 : if (oomvalue == NULL) /* supply a useful default */ 100 0 : oomvalue = "0"; 101 : 102 0 : rc = write(fd, oomvalue, strlen(oomvalue)); 103 : (void) rc; 104 0 : close(fd); 105 : } 106 : } 107 : 108 : /* do post-fork initialization for random number generation */ 109 22742 : pg_strong_random_init(); 110 : } 111 : 112 47724 : return result; 113 : } 114 : 115 : #endif /* ! WIN32 */