|
31 | 31 | fork_process(void)
|
32 | 32 | {
|
33 | 33 | pid_t result;
|
| 34 | + const char *oomfilename; |
34 | 35 |
|
35 | 36 | #ifdef LINUX_PROFILE
|
36 | 37 | struct itimerval prof_itimer;
|
@@ -71,62 +72,40 @@ fork_process(void)
|
71 | 72 | * process sizes *including shared memory*. (This is unbelievably
|
72 | 73 | * stupid, but the kernel hackers seem uninterested in improving it.)
|
73 | 74 | * Therefore it's often a good idea to protect the postmaster by
|
74 |
| - * setting its oom_score_adj value negative (which has to be done in a |
75 |
| - * root-owned startup script). If you just do that much, all child |
76 |
| - * processes will also be protected against OOM kill, which might not |
77 |
| - * be desirable. You can then choose to build with |
78 |
| - * LINUX_OOM_SCORE_ADJ #defined to 0, or to some other value that you |
79 |
| - * want child processes to adopt here. |
| 75 | + * setting its OOM score adjustment negative (which has to be done in |
| 76 | + * a root-owned startup script). Since the adjustment is inherited by |
| 77 | + * child processes, this would ordinarily mean that all the |
| 78 | + * postmaster's children are equally protected against OOM kill, which |
| 79 | + * is not such a good idea. So we provide this code to allow the |
| 80 | + * children to change their OOM score adjustments again. Both the |
| 81 | + * file name to write to and the value to write are controlled by |
| 82 | + * environment variables, which can be set by the same startup script |
| 83 | + * that did the original adjustment. |
80 | 84 | */
|
81 |
| -#ifdef LINUX_OOM_SCORE_ADJ |
82 |
| - { |
83 |
| - /* |
84 |
| - * Use open() not stdio, to ensure we control the open flags. Some |
85 |
| - * Linux security environments reject anything but O_WRONLY. |
86 |
| - */ |
87 |
| - int fd = open("/proc/self/oom_score_adj", O_WRONLY, 0); |
88 |
| - |
89 |
| - /* We ignore all errors */ |
90 |
| - if (fd >= 0) |
91 |
| - { |
92 |
| - char buf[16]; |
93 |
| - int rc; |
| 85 | + oomfilename = getenv("PG_OOM_ADJUST_FILE"); |
94 | 86 |
|
95 |
| - snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_SCORE_ADJ); |
96 |
| - rc = write(fd, buf, strlen(buf)); |
97 |
| - (void) rc; |
98 |
| - close(fd); |
99 |
| - } |
100 |
| - } |
101 |
| -#endif /* LINUX_OOM_SCORE_ADJ */ |
102 |
| - |
103 |
| - /* |
104 |
| - * Older Linux kernels have oom_adj not oom_score_adj. This works |
105 |
| - * similarly except with a different scale of adjustment values. If |
106 |
| - * it's necessary to build Postgres to work with either API, you can |
107 |
| - * define both LINUX_OOM_SCORE_ADJ and LINUX_OOM_ADJ. |
108 |
| - */ |
109 |
| -#ifdef LINUX_OOM_ADJ |
| 87 | + if (oomfilename != NULL) |
110 | 88 | {
|
111 | 89 | /*
|
112 | 90 | * Use open() not stdio, to ensure we control the open flags. Some
|
113 | 91 | * Linux security environments reject anything but O_WRONLY.
|
114 | 92 | */
|
115 |
| - int fd = open("/proc/self/oom_adj", O_WRONLY, 0); |
| 93 | + int fd = open(oomfilename, O_WRONLY, 0); |
116 | 94 |
|
117 | 95 | /* We ignore all errors */
|
118 | 96 | if (fd >= 0)
|
119 | 97 | {
|
120 |
| - char buf[16]; |
| 98 | + const char *oomvalue = getenv("PG_OOM_ADJUST_VALUE"); |
121 | 99 | int rc;
|
122 | 100 |
|
123 |
| - snprintf(buf, sizeof(buf), "%d\n", LINUX_OOM_ADJ); |
124 |
| - rc = write(fd, buf, strlen(buf)); |
| 101 | + if (oomvalue == NULL) /* supply a useful default */ |
| 102 | + oomvalue = "0"; |
| 103 | + |
| 104 | + rc = write(fd, oomvalue, strlen(oomvalue)); |
125 | 105 | (void) rc;
|
126 | 106 | close(fd);
|
127 | 107 | }
|
128 | 108 | }
|
129 |
| -#endif /* LINUX_OOM_ADJ */ |
130 | 109 |
|
131 | 110 | /*
|
132 | 111 | * Make sure processes do not share OpenSSL randomness state.
|
|
0 commit comments