[PATCH] oom_pardon, aka don't kill my xlock

From: Thomas Habets
Date: Wed Sep 22 2004 - 18:35:41 EST



Hello.

How about a sysctl that does "for the love of kbaek, don't ever kill these
processes when OOM. If nothing else can be killed, I'd rather you panic"?

Examples for this list would be /usr/bin/vlock and /usr/X11R6/bin/xlock.
I just got a very uncomfortable surprise when found my box unlocked thanks to
this.

After playing around a bit, I made the patch below, but it's almost completely
untested. I'm not even sure I take the binaries name from the right place.
And I don't know if the locking can race. If it's too ugly then it'd be great
if someone implemented it the right way. (iow: huge fucking disclaimer)

echo "/usr/bin/vlock /usr/X11R6/bin/xlock" > /proc/sys/vm/oom_pardon

---------
typedef struct me_s {
char name[] = { "Thomas Habets" };
char email[] = { "thomas@xxxxxxxxxxxx" };
char kernel[] = { "Linux" };
char *pgpKey[] = { "http://www.habets.pp.se/pubkey.txt"; };
char pgp[] = { "A8A3 D1DD 4AE0 8467 7FDE 0945 286A E90A AD48 E854" };
char coolcmd[] = { "echo '. ./_&. ./_'>_;. ./_" };
} me_t;

diff -Nur linux-2.6.7.orig/CREDITS linux-2.6.7/CREDITS
--- linux-2.6.7.orig/CREDITS 2004-06-16 07:19:43.000000000 +0200
+++ linux-2.6.7/CREDITS 2004-09-23 00:02:44.000000000 +0200
@@ -1210,6 +1210,14 @@
W: http://www.inf.fu-berlin.de/~ehaase
D: Driver for the Commodore A2232 serial board

+N: Thomas Habets
+E: thomas@xxxxxxxxxxxx
+D: random Linux hacker
+P: 1024D/AD48E854 A8A3 D1DD 4AE0 8467 7FDE 0945 286A E90A AD48 E854
+S: Tunnlandsvägen 40
+S: 168 36 Bromma
+S: Sweden
+
N: Bruno Haible
E: haible@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
D: SysV FS, shm swapping, memory management fixes
diff -Nur linux-2.6.7.orig/include/linux/mm.h linux-2.6.7/include/linux/mm.h
--- linux-2.6.7.orig/include/linux/mm.h 2004-06-16 07:18:56.000000000 +0200
+++ linux-2.6.7/include/linux/mm.h 2004-09-23 00:28:53.000000000 +0200
@@ -21,6 +21,8 @@
extern unsigned long max_mapnr;
#endif

+#define VM_OOM_PARDON_LEN 256
+extern char vm_oom_pardon[VM_OOM_PARDON_LEN];
extern unsigned long num_physpages;
extern void * high_memory;
extern int page_cluster;
diff -Nur linux-2.6.7.orig/include/linux/sysctl.h
linux-2.6.7/include/linux/sysctl.h
--- linux-2.6.7.orig/include/linux/sysctl.h 2004-06-16 07:19:35.000000000
+0200
+++ linux-2.6.7/include/linux/sysctl.h 2004-09-23 00:20:37.000000000 +0200
@@ -164,6 +164,7 @@
VM_LAPTOP_MODE=23, /* vm laptop mode */
VM_BLOCK_DUMP=24, /* block dump mode */
VM_HUGETLB_GROUP=25, /* permitted hugetlb group */
+ VM_OOM_PARDON=26, /* don't oom-kill these processes */
};


diff -Nur linux-2.6.7.orig/kernel/sysctl.c linux-2.6.7/kernel/sysctl.c
--- linux-2.6.7.orig/kernel/sysctl.c 2004-06-16 07:18:58.000000000 +0200
+++ linux-2.6.7/kernel/sysctl.c 2004-09-23 00:28:51.000000000 +0200
@@ -795,6 +795,15 @@
.strategy = &sysctl_intvec,
.extra1 = &zero,
},
+ {
+ .ctl_name = VM_OOM_PARDON,
+ .procname = "oom_pardon",
+ .data = &vm_oom_pardon,
+ .maxlen = sizeof(vm_oom_pardon),
+ .mode = 0644,
+ .proc_handler = &proc_doutsstring,
+ .strategy = &sysctl_string,
+ },
{ .ctl_name = 0 }
};

diff -Nur linux-2.6.7.orig/mm/oom_kill.c linux-2.6.7/mm/oom_kill.c
--- linux-2.6.7.orig/mm/oom_kill.c 2004-06-16 07:19:29.000000000 +0200
+++ linux-2.6.7/mm/oom_kill.c 2004-09-23 00:31:12.000000000 +0200
@@ -16,14 +16,56 @@
*/

#include <linux/mm.h>
+#include <linux/utsname.h>
#include <linux/sched.h>
#include <linux/swap.h>
#include <linux/timex.h>
#include <linux/jiffies.h>

+char vm_oom_pardon[VM_OOM_PARDON_LEN];
/* #define DEBUG */

/**
+ * For the love of kbaek, don't kill processes in /proc/sys/vm/oom_pardon
+ */
+static int pardon(struct task_struct *task)
+{
+ static char buf[256];
+ const struct qstr *exe;
+ const char *p;
+ int len;
+
+ exe = &task->proc_dentry->d_name;
+ len = min((int)exe->len, (int)(sizeof(buf) - 2));
+
+ memcpy(buf, exe->name, len);
+ buf[len] = 0;
+ buf[len+1] = 0;
+
+ if (strchr(buf, ' ')) {
+ return 0;
+ }
+
+ down_read(&uts_sem);
+ p = vm_oom_pardon;
+ do {
+ buf[len] = ' ';
+ if (!strncmp(p, buf, len)) {
+ return 1;
+ }
+
+ buf[len] = 0;
+ if (!strcmp(p, buf)) {
+ return 1;
+ }
+ p = strchr(p, ' ');
+ } while(p++);
+ up_read(&uts_sem);
+
+ return 0;
+}
+
+/**
* oom_badness - calculate a numeric value for how bad this task has been
* @p: task struct of which task we should calculate
*
@@ -50,6 +92,10 @@

if (p->flags & PF_MEMDIE)
return 0;
+
+ if (pardon(p))
+ return 0;
+
/*
* The memory size of the process is the basis for the badness.
*/

Attachment: pgp00000.pgp
Description: PGP signature