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