On Tue, Jun 10, 2014 at 12:05 PM, Tom Lane <t...@sss.pgh.pa.us> wrote:
> If we're going to do this, I would say that we should also take the
> opportunity to get out from under the question of which kernel API
> we're dealing with.  So perhaps a design like this:
>
> 1. If the environment variable PG_OOM_ADJUST_FILE is defined, it's
> the name of a file to write something into after forking.  The typical
> value would be "/proc/self/oom_score_adj" or "/proc/self/oom_adj".
> If not set, nothing happens.
>
> 2. If the environment variable PG_OOM_ADJUST_VALUE is defined, that's
> the string we write, otherwise we write "0".

Please find attached the patch. It includes the doc changes as well.

Best regards,
-- 
Gurjeet Singh http://gurjeet.singh.im/

EDB www.EnterpriseDB.com
diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 9fadef5..4492a1d 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1284,8 +1284,15 @@ echo -1000 > /proc/self/oom_score_adj
     in the postmaster's startup script just before invoking the postmaster.
     Note that this action must be done as root, or it will have no effect;
     so a root-owned startup script is the easiest place to do it.  If you
-    do this, you may also wish to build <productname>PostgreSQL</>
-    with <literal>-DLINUX_OOM_SCORE_ADJ=0</> added to <varname>CPPFLAGS</>.
+    do this, you may also wish to export these environment variables
+<programlisting>
+PG_OOM_ADJUST_FILE=oom_score_adj
+PG_OOM_ADJUST_VALUE=0
+
+export PG_OOM_ADJUST_FILE
+export PG_OOM_ADJUST_VALUE
+</programlisting>
+    in the startup script, before invoking the postmaster.
     That will cause postmaster child processes to run with the normal
     <varname>oom_score_adj</> value of zero, so that the OOM killer can still
     target them at need.
@@ -1296,8 +1303,7 @@ echo -1000 > /proc/self/oom_score_adj
     but may have a previous version of the same functionality called
     <filename>/proc/self/oom_adj</>.  This works the same except the disable
     value is <literal>-17</> not <literal>-1000</>.  The corresponding
-    build flag for <productname>PostgreSQL</> is
-    <literal>-DLINUX_OOM_ADJ=0</>.
+    value for <envar>PG_OOM_ADJUST_FILE</> should be <varname>oom_adj</>.
    </para>
 
    <note>
diff --git a/src/backend/postmaster/fork_process.c b/src/backend/postmaster/fork_process.c
index f6df2de..21559af 100644
--- a/src/backend/postmaster/fork_process.c
+++ b/src/backend/postmaster/fork_process.c
@@ -22,6 +22,13 @@
 #endif
 
 #ifndef WIN32
+
+#ifdef __linux__
+static bool	oom_env_checked = false;
+static char	oom_adj_file[MAXPGPATH];
+static int	oom_adj_value = 0;
+#endif	/* __linux__ */
+
 /*
  * Wrapper for fork(). Return values are the same as those for fork():
  * -1 if the fork failed, 0 in the child process, and the PID of the
@@ -78,13 +85,38 @@ fork_process(void)
 		 * LINUX_OOM_SCORE_ADJ #defined to 0, or to some other value that you
 		 * want child processes to adopt here.
 		 */
-#ifdef LINUX_OOM_SCORE_ADJ
+#ifdef __linux__
+		if (!oom_env_checked)
+		{
+			char *env;
+
+			oom_env_checked = true;
+
+			env = getenv("PG_OOM_ADJUST_FILE");
+
+			/* Don't allow a path separator in file name */
+			if (env && !strchr(env, '/') && !strchr(env, '\\'))
+			{
+				snprintf(oom_adj_file, MAXPGPATH, "/proc/self/%s", env);
+
+				env = getenv("PG_OOM_ADJUST_VALUE");
+				if (env)
+				{
+					oom_adj_value = atoi(env);
+				}
+				else
+					oom_adj_value = 0;
+			}
+			else
+				oom_adj_file[0] = '\0';
+		}
+
 		{
 			/*
 			 * 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_score_adj", O_WRONLY, 0);
+			int			fd = open(oom_adj_file, O_WRONLY, 0);
 
 			/* We ignore all errors */
 			if (fd >= 0)
@@ -92,41 +124,14 @@ fork_process(void)
 				char		buf[16];
 				int			rc;
 
-				snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_SCORE_ADJ);
+				snprintf(buf, sizeof(buf), "%d\n", oom_adj_value);
 				rc = write(fd, buf, strlen(buf));
 				(void) rc;
 				close(fd);
 			}
 		}
-#endif   /* LINUX_OOM_SCORE_ADJ */
 
-		/*
-		 * Older Linux kernels have oom_adj not oom_score_adj.  This works
-		 * similarly except with a different scale of adjustment values. If
-		 * it's necessary to build Postgres to work with either API, you can
-		 * define both LINUX_OOM_SCORE_ADJ and LINUX_OOM_ADJ.
-		 */
-#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];
-				int			rc;
-
-				snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_ADJ);
-				rc = write(fd, buf, strlen(buf));
-				(void) rc;
-				close(fd);
-			}
-		}
-#endif   /* LINUX_OOM_ADJ */
+#endif   /* __linux__ */
 
 		/*
 		 * Make sure processes do not share OpenSSL randomness state.
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to