#include <linux/suspend.h>
#include <linux/writeback.h>
#include <linux/buffer_head.h> /* for fsync_bdev() */
-
+#include <linux/swap.h>
#include <linux/spinlock.h>
+#include <linux/vt_kern.h>
+#include <linux/workqueue.h>
#include <asm/ptrace.h>
-extern void reset_vc(unsigned int);
-
/* Whether we react on sysrq keys or just ignore them */
int sysrq_enabled = 1;
-/* Machine specific power off function */
-void (*sysrq_power_off)(void);
-
/* Loglevel sysrq handler */
static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs,
struct tty_struct *tty)
.handler = sysrq_handle_loglevel,
.help_msg = "loglevel0-8",
.action_msg = "Changing Loglevel",
+ .enable_mask = SYSRQ_ENABLE_LOG,
};
{
if (tty)
do_SAK(tty);
- reset_vc(fg_console);
+ reset_vc(vc_cons[fg_console].d);
}
static struct sysrq_key_op sysrq_SAK_op = {
.handler = sysrq_handle_SAK,
.help_msg = "saK",
.action_msg = "SAK",
+ .enable_mask = SYSRQ_ENABLE_KEYBOARD,
};
#endif
.handler = sysrq_handle_unraw,
.help_msg = "unRaw",
.action_msg = "Keyboard mode set to XLATE",
+ .enable_mask = SYSRQ_ENABLE_KEYBOARD,
};
#endif /* CONFIG_VT */
.handler = sysrq_handle_reboot,
.help_msg = "reBoot",
.action_msg = "Resetting",
+ .enable_mask = SYSRQ_ENABLE_BOOT,
};
static void sysrq_handle_sync(int key, struct pt_regs *pt_regs,
.handler = sysrq_handle_sync,
.help_msg = "Sync",
.action_msg = "Emergency Sync",
+ .enable_mask = SYSRQ_ENABLE_SYNC,
};
static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs,
.handler = sysrq_handle_mountro,
.help_msg = "Unmount",
.action_msg = "Emergency Remount R/O",
+ .enable_mask = SYSRQ_ENABLE_REMOUNT,
};
/* END SYNC SYSRQ HANDLERS BLOCK */
.handler = sysrq_handle_showregs,
.help_msg = "showPc",
.action_msg = "Show Regs",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
};
.handler = sysrq_handle_showstate,
.help_msg = "showTasks",
.action_msg = "Show State",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
};
.handler = sysrq_handle_showmem,
.help_msg = "showMem",
.action_msg = "Show Memory",
+ .enable_mask = SYSRQ_ENABLE_DUMP,
};
/* SHOW SYSRQ HANDLERS BLOCK */
.handler = sysrq_handle_term,
.help_msg = "tErm",
.action_msg = "Terminate All Tasks",
+ .enable_mask = SYSRQ_ENABLE_SIGNAL,
+};
+
+static void moom_callback(void *ignored)
+{
+ out_of_memory(GFP_KERNEL);
+}
+
+static DECLARE_WORK(moom_work, moom_callback, NULL);
+
+static void sysrq_handle_moom(int key, struct pt_regs *pt_regs,
+ struct tty_struct *tty)
+{
+ schedule_work(&moom_work);
+}
+static struct sysrq_key_op sysrq_moom_op = {
+ .handler = sysrq_handle_moom,
+ .help_msg = "Full",
+ .action_msg = "Manual OOM execution",
};
static void sysrq_handle_kill(int key, struct pt_regs *pt_regs,
.handler = sysrq_handle_kill,
.help_msg = "kIll",
.action_msg = "Kill All Tasks",
+ .enable_mask = SYSRQ_ENABLE_SIGNAL,
};
/* END SIGNAL SYSRQ HANDLERS BLOCK */
static struct sysrq_key_op sysrq_unrt_op = {
.handler = sysrq_handle_unrt,
.help_msg = "Nice",
- .action_msg = "Nice All RT Tasks"
+ .action_msg = "Nice All RT Tasks",
+ .enable_mask = SYSRQ_ENABLE_RTNICE,
};
/* Key Operations table and lock */
/* c */ NULL,
/* d */ NULL,
/* e */ &sysrq_term_op,
-/* f */ NULL,
+/* f */ &sysrq_moom_op,
/* g */ NULL,
/* h */ NULL,
/* i */ &sysrq_kill_op,
* as they are inside of the lock
*/
-void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty)
+void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty, int check_mask)
{
struct sysrq_key_op *op_p;
int orig_log_level;
op_p = __sysrq_get_key_op(key);
if (op_p) {
- printk ("%s\n", op_p->action_msg);
- console_loglevel = orig_log_level;
- op_p->handler(key, pt_regs, tty);
+ /* Should we check for enabled operations (/proc/sysrq-trigger should not)
+ * and is the invoked operation enabled? */
+ if (!check_mask || sysrq_enabled == 1 ||
+ (sysrq_enabled & op_p->enable_mask)) {
+ printk ("%s\n", op_p->action_msg);
+ console_loglevel = orig_log_level;
+ op_p->handler(key, pt_regs, tty);
+ }
+ else
+ printk("This sysrq operation is disabled.\n");
} else {
printk("HELP : ");
/* Only print the help msg once per handler */
{
if (!sysrq_enabled)
return;
- __handle_sysrq(key, pt_regs, tty);
+ __handle_sysrq(key, pt_regs, tty, 1);
}
int __sysrq_swap_key_ops(int key, struct sysrq_key_op *insert_op_p,