2 * Handle extern requests for shutdown, reboot and sysrq
4 #include <linux/kernel.h>
6 #include <linux/reboot.h>
7 #include <linux/sysrq.h>
9 #include <xen/xenbus.h>
11 #define SHUTDOWN_INVALID -1
12 #define SHUTDOWN_POWEROFF 0
13 #define SHUTDOWN_SUSPEND 2
14 /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
15 * report a crash, not be instructed to crash!
16 * HALT is the same as POWEROFF, as far as we're concerned. The tools use
17 * the distinction when we return the reason code to them.
19 #define SHUTDOWN_HALT 4
21 /* Ignore multiple shutdown requests. */
22 static int shutting_down = SHUTDOWN_INVALID;
24 static void shutdown_handler(struct xenbus_watch *watch,
25 const char **vec, unsigned int len)
28 struct xenbus_transaction xbt;
31 if (shutting_down != SHUTDOWN_INVALID)
35 err = xenbus_transaction_start(&xbt);
39 str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
40 /* Ignore read errors and empty reads. */
41 if (XENBUS_IS_ERR_READ(str)) {
42 xenbus_transaction_end(xbt, 1);
46 xenbus_write(xbt, "control", "shutdown", "");
48 err = xenbus_transaction_end(xbt, 0);
54 if (strcmp(str, "poweroff") == 0 ||
55 strcmp(str, "halt") == 0)
56 orderly_poweroff(false);
57 else if (strcmp(str, "reboot") == 0)
60 printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
61 shutting_down = SHUTDOWN_INVALID;
67 static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
70 char sysrq_key = '\0';
71 struct xenbus_transaction xbt;
75 err = xenbus_transaction_start(&xbt);
78 if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
79 printk(KERN_ERR "Unable to read sysrq code in "
81 xenbus_transaction_end(xbt, 1);
85 if (sysrq_key != '\0')
86 xenbus_printf(xbt, "control", "sysrq", "%c", '\0');
88 err = xenbus_transaction_end(xbt, 0);
92 if (sysrq_key != '\0')
93 handle_sysrq(sysrq_key, NULL);
96 static struct xenbus_watch shutdown_watch = {
97 .node = "control/shutdown",
98 .callback = shutdown_handler
101 static struct xenbus_watch sysrq_watch = {
102 .node = "control/sysrq",
103 .callback = sysrq_handler
106 static int setup_shutdown_watcher(void)
110 err = register_xenbus_watch(&shutdown_watch);
112 printk(KERN_ERR "Failed to set shutdown watcher\n");
116 err = register_xenbus_watch(&sysrq_watch);
118 printk(KERN_ERR "Failed to set sysrq watcher\n");
125 static int shutdown_event(struct notifier_block *notifier,
129 setup_shutdown_watcher();
133 static int __init setup_shutdown_event(void)
135 static struct notifier_block xenstore_notifier = {
136 .notifier_call = shutdown_event
138 register_xenstore_notifier(&xenstore_notifier);
143 subsys_initcall(setup_shutdown_event);