diff -urN linux-2.4.0-test6-pre8/include/linux/kernel.h linux-2.4.0-test6-pre8-patched/include/linux/kernel.h --- linux-2.4.0-test6-pre8/include/linux/kernel.h Tue Jun 20 10:52:36 2000 +++ linux-2.4.0-test6-pre8-patched/include/linux/kernel.h Tue Aug 8 16:46:07 2000 @@ -44,7 +44,10 @@ #define FASTCALL(x) x #endif +extern int panic_on_oops; extern struct notifier_block *panic_notifier_list; +extern int register_panic_notifier(struct notifier_block * nb); +extern int unregister_panic_notifier(struct notifier_block * nb); NORET_TYPE void panic(const char * fmt, ...) __attribute__ ((NORET_AND format (printf, 1, 2))); NORET_TYPE void do_exit(long error_code) diff -urN linux-2.4.0-test6-pre8/include/linux/sysctl.h linux-2.4.0-test6-pre8-patched/include/linux/sysctl.h --- linux-2.4.0-test6-pre8/include/linux/sysctl.h Fri Jul 21 17:13:33 2000 +++ linux-2.4.0-test6-pre8-patched/include/linux/sysctl.h Tue Aug 8 16:31:44 2000 @@ -113,6 +113,7 @@ KERN_OVERFLOWGID=47, /* int: overflow GID */ KERN_SHMPATH=48, /* string: path to shm fs */ KERN_HOTPLUG=49, /* string: path to hotplug policy agent */ + KERN_PANIC_ON_OOPS=50, /* int: should we panic on an oops? */ }; diff -urN linux-2.4.0-test6-pre8/kernel/exit.c linux-2.4.0-test6-pre8-patched/kernel/exit.c --- linux-2.4.0-test6-pre8/kernel/exit.c Tue Aug 8 15:21:05 2000 +++ linux-2.4.0-test6-pre8-patched/kernel/exit.c Tue Aug 8 16:10:19 2000 @@ -437,6 +437,10 @@ panic("Attempted to kill the idle task!"); if (tsk->pid == 1) panic("Attempted to kill init!"); + + if(panic_on_oops) + panic("oops, forcing panic"); + tsk->flags |= PF_EXITING; del_timer_sync(&tsk->real_timer); diff -urN linux-2.4.0-test6-pre8/kernel/panic.c linux-2.4.0-test6-pre8-patched/kernel/panic.c --- linux-2.4.0-test6-pre8/kernel/panic.c Tue Jun 20 17:32:27 2000 +++ linux-2.4.0-test6-pre8-patched/kernel/panic.c Tue Aug 8 17:05:26 2000 @@ -21,9 +21,41 @@ extern void unblank_console(void); int panic_timeout; +int panic_on_oops = 0; struct notifier_block *panic_notifier_list = NULL; +/** + * register_panic_notifier - Register function to be called at panic time + * @nb: Info about notifier function to be called + * + * Registers a function with the list of functions + * to be called at panic time. + * + * Currently always returns zero, as notifier_chain_register + * always returns zero. + */ + +int register_panic_notifier(struct notifier_block * nb) +{ + return notifier_chain_register(&panic_notifier_list, nb); +} + +/** + * unregister_panic_notifier - Unregister previously registered panic notifier + * @nb: Hook to be unregistered + * + * Unregisters a previously registered panic + * notifier function. + * + * Returns zero on success, or %-ENOENT on failure. + */ + +int unregister_panic_notifier(struct notifier_block * nb) +{ + return notifier_chain_unregister(&panic_notifier_list, nb); +} + static int __init panic_setup(char *str) { panic_timeout = simple_strtoul(str, NULL, 0); @@ -46,11 +78,19 @@ NORET_TYPE void panic(const char * fmt, ...) { static char buf[1024]; + static int panicing = 0; va_list args; #if defined(CONFIG_ARCH_S390) unsigned long caller = (unsigned long) __builtin_return_address(0); #endif + if (panicing) + goto out; + + panicing = 1; + unblank_console(); + notifier_call_chain(&panic_notifier_list, 0, NULL); + va_start(args, fmt); vsprintf(buf, fmt, args); va_end(args); @@ -62,14 +102,11 @@ else sys_sync(); - unblank_console(); - #ifdef CONFIG_SMP smp_send_stop(); #endif - - notifier_call_chain(&panic_notifier_list, 0, NULL); - + + out: if (panic_timeout > 0) { /* @@ -101,3 +138,6 @@ CHECK_EMERGENCY_SYNC } } + +EXPORT_SYMBOL(register_panic_notifier); +EXPORT_SYMBOL(unregister_panic_notifier); diff -urN linux-2.4.0-test6-pre8/kernel/sysctl.c linux-2.4.0-test6-pre8-patched/kernel/sysctl.c --- linux-2.4.0-test6-pre8/kernel/sysctl.c Tue Aug 8 15:21:05 2000 +++ linux-2.4.0-test6-pre8-patched/kernel/sysctl.c Tue Aug 8 16:30:20 2000 @@ -230,6 +230,8 @@ {KERN_OVERFLOWGID, "overflowgid", &overflowgid, sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, &minolduid, &maxolduid}, + {KERN_PANIC_ON_OOPS, "panic_on_oops", &panic_on_oops, sizeof(int), + 0644, NULL, &proc_dointvec}, {0} };