Sophie

Sophie

distrib > Fedora > 13 > i386 > media > updates-src > by-pkgid > 059dea8de81702baf47ef06a8a95d8b6 > files > 12

postgresql-8.4.8-1.fc13.src.rpm

Back-ported patch from Postgres devel head: reset oom_adj to zero in any
postmaster child process.  This allows us to disable OOM kill on the postmaster
(see the init script) without affecting OOM behavior for child processes.


diff -Naur postgresql-8.4.2.orig/src/backend/postmaster/fork_process.c postgresql-8.4.2/src/backend/postmaster/fork_process.c
--- postgresql-8.4.2.orig/src/backend/postmaster/fork_process.c	2009-01-01 12:23:46.000000000 -0500
+++ postgresql-8.4.2/src/backend/postmaster/fork_process.c	2010-01-11 12:28:17.000000000 -0500
@@ -12,7 +12,9 @@
 #include "postgres.h"
 #include "postmaster/fork_process.h"
 
+#include <fcntl.h>
 #include <time.h>
+#include <sys/stat.h>
 #include <sys/time.h>
 #include <unistd.h>
 
@@ -60,6 +62,38 @@
 		setitimer(ITIMER_PROF, &prof_itimer, NULL);
 #endif
 
+		/*
+		 * By default, Linux tends to kill the postmaster in out-of-memory
+		 * situations, because it blames the postmaster for the sum of child
+		 * process sizes *including shared memory*.  (This is unbelievably
+		 * stupid, but the kernel hackers seem uninterested in improving it.)
+		 * Therefore it's often a good idea to protect the postmaster by
+		 * setting its oom_adj value negative (which has to be done in a
+		 * root-owned startup script).  If you just do that much, all child
+		 * processes will also be protected against OOM kill, which might not
+		 * be desirable.  You can then choose to build with LINUX_OOM_ADJ
+		 * #defined to 0, or some other value that you want child processes
+		 * to adopt here.
+		 */
+#ifdef LINUX_OOM_ADJ
+		{
+			/*
+			 * Use open() not stdio, to ensure we control the open flags.
+			 * Some Linux security environments reject anything but O_WRONLY.
+			 */
+			int		fd = open("/proc/self/oom_adj", O_WRONLY, 0);
+
+			/* We ignore all errors */
+			if (fd >= 0)
+			{
+				char	buf[16];
+
+				snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_ADJ);
+				(void) write(fd, buf, strlen(buf));
+				close(fd);
+			}
+		}
+#endif /* LINUX_OOM_ADJ */
 	}
 
 	return result;