00001 /* 00002 * fork_process.c 00003 * A simple wrapper on top of fork(). This does not handle the 00004 * EXEC_BACKEND case; it might be extended to do so, but it would be 00005 * considerably more complex. 00006 * 00007 * Copyright (c) 1996-2013, PostgreSQL Global Development Group 00008 * 00009 * IDENTIFICATION 00010 * src/backend/postmaster/fork_process.c 00011 */ 00012 #include "postgres.h" 00013 #include "postmaster/fork_process.h" 00014 00015 #include <fcntl.h> 00016 #include <time.h> 00017 #include <sys/stat.h> 00018 #include <sys/time.h> 00019 #include <unistd.h> 00020 #ifdef USE_SSL 00021 #include <openssl/rand.h> 00022 #endif 00023 00024 #ifndef WIN32 00025 /* 00026 * Wrapper for fork(). Return values are the same as those for fork(): 00027 * -1 if the fork failed, 0 in the child process, and the PID of the 00028 * child in the parent process. 00029 */ 00030 pid_t 00031 fork_process(void) 00032 { 00033 pid_t result; 00034 00035 #ifdef LINUX_PROFILE 00036 struct itimerval prof_itimer; 00037 #endif 00038 00039 /* 00040 * Flush stdio channels just before fork, to avoid double-output problems. 00041 * Ideally we'd use fflush(NULL) here, but there are still a few non-ANSI 00042 * stdio libraries out there (like SunOS 4.1.x) that coredump if we do. 00043 * Presently stdout and stderr are the only stdio output channels used by 00044 * the postmaster, so fflush'ing them should be sufficient. 00045 */ 00046 fflush(stdout); 00047 fflush(stderr); 00048 00049 #ifdef LINUX_PROFILE 00050 00051 /* 00052 * Linux's fork() resets the profiling timer in the child process. If we 00053 * want to profile child processes then we need to save and restore the 00054 * timer setting. This is a waste of time if not profiling, however, so 00055 * only do it if commanded by specific -DLINUX_PROFILE switch. 00056 */ 00057 getitimer(ITIMER_PROF, &prof_itimer); 00058 #endif 00059 00060 result = fork(); 00061 if (result == 0) 00062 { 00063 /* fork succeeded, in child */ 00064 #ifdef LINUX_PROFILE 00065 setitimer(ITIMER_PROF, &prof_itimer, NULL); 00066 #endif 00067 00068 /* 00069 * By default, Linux tends to kill the postmaster in out-of-memory 00070 * situations, because it blames the postmaster for the sum of child 00071 * process sizes *including shared memory*. (This is unbelievably 00072 * stupid, but the kernel hackers seem uninterested in improving it.) 00073 * Therefore it's often a good idea to protect the postmaster by 00074 * setting its oom_score_adj value negative (which has to be done in a 00075 * root-owned startup script). If you just do that much, all child 00076 * processes will also be protected against OOM kill, which might not 00077 * be desirable. You can then choose to build with 00078 * LINUX_OOM_SCORE_ADJ #defined to 0, or to some other value that you 00079 * want child processes to adopt here. 00080 */ 00081 #ifdef LINUX_OOM_SCORE_ADJ 00082 { 00083 /* 00084 * Use open() not stdio, to ensure we control the open flags. Some 00085 * Linux security environments reject anything but O_WRONLY. 00086 */ 00087 int fd = open("/proc/self/oom_score_adj", O_WRONLY, 0); 00088 00089 /* We ignore all errors */ 00090 if (fd >= 0) 00091 { 00092 char buf[16]; 00093 int rc; 00094 00095 snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_SCORE_ADJ); 00096 rc = write(fd, buf, strlen(buf)); 00097 (void) rc; 00098 close(fd); 00099 } 00100 } 00101 #endif /* LINUX_OOM_SCORE_ADJ */ 00102 00103 /* 00104 * Older Linux kernels have oom_adj not oom_score_adj. This works 00105 * similarly except with a different scale of adjustment values. 00106 * If it's necessary to build Postgres to work with either API, 00107 * you can define both LINUX_OOM_SCORE_ADJ and LINUX_OOM_ADJ. 00108 */ 00109 #ifdef LINUX_OOM_ADJ 00110 { 00111 /* 00112 * Use open() not stdio, to ensure we control the open flags. Some 00113 * Linux security environments reject anything but O_WRONLY. 00114 */ 00115 int fd = open("/proc/self/oom_adj", O_WRONLY, 0); 00116 00117 /* We ignore all errors */ 00118 if (fd >= 0) 00119 { 00120 char buf[16]; 00121 int rc; 00122 00123 snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_ADJ); 00124 rc = write(fd, buf, strlen(buf)); 00125 (void) rc; 00126 close(fd); 00127 } 00128 } 00129 #endif /* LINUX_OOM_ADJ */ 00130 00131 /* 00132 * Make sure processes do not share OpenSSL randomness state. 00133 */ 00134 #ifdef USE_SSL 00135 RAND_cleanup(); 00136 #endif 00137 } 00138 00139 return result; 00140 } 00141 00142 #endif /* ! WIN32 */