On Tue, Jun 10, 2014 at 12:05 PM, Tom Lane <[email protected]> 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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers