117 lines
2.8 KiB
Diff
117 lines
2.8 KiB
Diff
WHATS_NEW_DM | 1 +
|
|
daemons/dmeventd/dmeventd.c | 61 +++++++++++++++++++++++++++++-------------
|
|
2 files changed, 43 insertions(+), 19 deletions(-)
|
|
|
|
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
|
|
index b6a5360..868a469 100644
|
|
--- a/WHATS_NEW_DM
|
|
+++ b/WHATS_NEW_DM
|
|
@@ -1,5 +1,6 @@
|
|
Version 1.02.66 -
|
|
===============================
|
|
+ Add support for new oom killer adjustment interface (oom_score_adj).
|
|
Add systemd unit files for dmeventd.
|
|
|
|
Version 1.02.65 - 8th July 2011
|
|
diff --git a/daemons/dmeventd/dmeventd.c b/daemons/dmeventd/dmeventd.c
|
|
index 1a91cb8..a6956cb 100644
|
|
--- a/daemons/dmeventd/dmeventd.c
|
|
+++ b/daemons/dmeventd/dmeventd.c
|
|
@@ -41,11 +41,19 @@
|
|
#ifdef linux
|
|
# include <malloc.h>
|
|
|
|
-# define OOM_ADJ_FILE "/proc/self/oom_adj"
|
|
+/*
|
|
+ * Kernel version 2.6.36 and higher has
|
|
+ * new OOM killer adjustment interface.
|
|
+ */
|
|
+# define OOM_ADJ_FILE_OLD "/proc/self/oom_adj"
|
|
+# define OOM_ADJ_FILE "/proc/self/oom_score_adj"
|
|
|
|
/* From linux/oom.h */
|
|
+/* Old interface */
|
|
# define OOM_DISABLE (-17)
|
|
# define OOM_ADJUST_MIN (-16)
|
|
+/* New interface */
|
|
+# define OOM_SCORE_ADJ_MIN (-1000)
|
|
|
|
#endif
|
|
|
|
@@ -1594,33 +1602,48 @@ static void _exit_handler(int sig __attribute__((unused)))
|
|
}
|
|
|
|
#ifdef linux
|
|
+static int _set_oom_adj(const char *oom_adj_path, int val)
|
|
+{
|
|
+ FILE *fp;
|
|
+
|
|
+ if (!(fp = fopen(oom_adj_path, "w"))) {
|
|
+ perror("oom_adj: fopen failed");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ fprintf(fp, "%i", val);
|
|
+
|
|
+ if (dm_fclose(fp))
|
|
+ perror("oom_adj: fclose failed");
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
/*
|
|
* Protection against OOM killer if kernel supports it
|
|
*/
|
|
-static int _set_oom_adj(int val)
|
|
+static int _protect_against_oom_killer()
|
|
{
|
|
- FILE *fp;
|
|
-
|
|
struct stat st;
|
|
|
|
if (stat(OOM_ADJ_FILE, &st) == -1) {
|
|
- if (errno == ENOENT)
|
|
- perror(OOM_ADJ_FILE " not found");
|
|
- else
|
|
+ if (errno != ENOENT)
|
|
perror(OOM_ADJ_FILE ": stat failed");
|
|
- return 1;
|
|
- }
|
|
|
|
- if (!(fp = fopen(OOM_ADJ_FILE, "w"))) {
|
|
- perror(OOM_ADJ_FILE ": fopen failed");
|
|
- return 0;
|
|
- }
|
|
+ /* Try old oom_adj interface as a fallback */
|
|
+ if (stat(OOM_ADJ_FILE_OLD, &st) == -1) {
|
|
+ if (errno == ENOENT)
|
|
+ perror(OOM_ADJ_FILE_OLD " not found");
|
|
+ else
|
|
+ perror(OOM_ADJ_FILE_OLD ": stat failed");
|
|
+ return 1;
|
|
+ }
|
|
|
|
- fprintf(fp, "%i", val);
|
|
- if (dm_fclose(fp))
|
|
- perror(OOM_ADJ_FILE ": fclose failed");
|
|
+ return _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_DISABLE) ||
|
|
+ _set_oom_adj(OOM_ADJ_FILE_OLD, OOM_ADJUST_MIN);
|
|
+ }
|
|
|
|
- return 1;
|
|
+ return _set_oom_adj(OOM_ADJ_FILE, OOM_SCORE_ADJ_MIN);
|
|
}
|
|
#endif
|
|
|
|
@@ -1829,8 +1852,8 @@ int main(int argc, char *argv[])
|
|
signal(SIGQUIT, &_exit_handler);
|
|
|
|
#ifdef linux
|
|
- if (!_set_oom_adj(OOM_DISABLE) && !_set_oom_adj(OOM_ADJUST_MIN))
|
|
- syslog(LOG_ERR, "Failed to set oom_adj to protect against OOM killer");
|
|
+ if (!_protect_against_oom_killer())
|
|
+ syslog(LOG_ERR, "Failed to protect against OOM killer");
|
|
#endif
|
|
|
|
_init_thread_signals();
|