2 * Handle extern requests for shutdown, reboot and sysrq
4 #include <linux/kernel.h>
6 #include <linux/slab.h>
7 #include <linux/reboot.h>
8 #include <linux/sysrq.h>
9 #include <linux/stop_machine.h>
10 #include <linux/freezer.h>
12 #include <xen/xenbus.h>
13 #include <xen/grant_table.h>
14 #include <xen/events.h>
15 #include <xen/hvc-console.h>
16 #include <xen/xen-ops.h>
18 #include <asm/xen/hypercall.h>
19 #include <asm/xen/page.h>
22 SHUTDOWN_INVALID
= -1,
23 SHUTDOWN_POWEROFF
= 0,
25 /* Code 3 is SHUTDOWN_CRASH, which we don't use because the domain can only
26 report a crash, not be instructed to crash!
27 HALT is the same as POWEROFF, as far as we're concerned. The tools use
28 the distinction when we return the reason code to them. */
32 /* Ignore multiple shutdown requests. */
33 static enum shutdown_state shutting_down
= SHUTDOWN_INVALID
;
35 #ifdef CONFIG_PM_SLEEP
36 static int xen_suspend(void *data
)
38 int *cancelled
= data
;
41 BUG_ON(!irqs_disabled());
43 err
= sysdev_suspend(PMSG_SUSPEND
);
45 printk(KERN_ERR
"xen_suspend: sysdev_suspend failed: %d\n",
55 * This hypercall returns 1 if suspend was cancelled
56 * or the domain was merely checkpointed, and 0 if it
57 * is resuming in a new domain.
59 *cancelled
= HYPERVISOR_suspend(virt_to_mfn(xen_start_info
));
61 xen_post_suspend(*cancelled
);
76 static void do_suspend(void)
81 shutting_down
= SHUTDOWN_SUSPEND
;
83 err
= stop_machine_create();
85 printk(KERN_ERR
"xen suspend: failed to setup stop_machine %d\n", err
);
90 /* If the kernel is preemptible, we need to freeze all the processes
91 to prevent them from being in the middle of a pagetable update
93 err
= freeze_processes();
95 printk(KERN_ERR
"xen suspend: freeze failed %d\n", err
);
100 err
= dpm_suspend_start(PMSG_SUSPEND
);
102 printk(KERN_ERR
"xen suspend: dpm_suspend_start %d\n", err
);
106 printk(KERN_DEBUG
"suspending xenstore...\n");
109 err
= dpm_suspend_noirq(PMSG_SUSPEND
);
111 printk(KERN_ERR
"dpm_suspend_noirq failed: %d\n", err
);
115 err
= stop_machine(xen_suspend
, &cancelled
, cpumask_of(0));
117 dpm_resume_noirq(PMSG_RESUME
);
120 printk(KERN_ERR
"failed to start xen_suspend: %d\n", err
);
131 dpm_resume_end(PMSG_RESUME
);
133 /* Make sure timer events get retriggered on all CPUs */
137 #ifdef CONFIG_PREEMPT
142 stop_machine_destroy();
145 shutting_down
= SHUTDOWN_INVALID
;
147 #endif /* CONFIG_PM_SLEEP */
149 static void shutdown_handler(struct xenbus_watch
*watch
,
150 const char **vec
, unsigned int len
)
153 struct xenbus_transaction xbt
;
156 if (shutting_down
!= SHUTDOWN_INVALID
)
160 err
= xenbus_transaction_start(&xbt
);
164 str
= (char *)xenbus_read(xbt
, "control", "shutdown", NULL
);
165 /* Ignore read errors and empty reads. */
166 if (XENBUS_IS_ERR_READ(str
)) {
167 xenbus_transaction_end(xbt
, 1);
171 xenbus_write(xbt
, "control", "shutdown", "");
173 err
= xenbus_transaction_end(xbt
, 0);
174 if (err
== -EAGAIN
) {
179 if (strcmp(str
, "poweroff") == 0 ||
180 strcmp(str
, "halt") == 0) {
181 shutting_down
= SHUTDOWN_POWEROFF
;
182 orderly_poweroff(false);
183 } else if (strcmp(str
, "reboot") == 0) {
184 shutting_down
= SHUTDOWN_POWEROFF
; /* ? */
186 #ifdef CONFIG_PM_SLEEP
187 } else if (strcmp(str
, "suspend") == 0) {
191 printk(KERN_INFO
"Ignoring shutdown request: %s\n", str
);
192 shutting_down
= SHUTDOWN_INVALID
;
198 static void sysrq_handler(struct xenbus_watch
*watch
, const char **vec
,
201 char sysrq_key
= '\0';
202 struct xenbus_transaction xbt
;
206 err
= xenbus_transaction_start(&xbt
);
209 if (!xenbus_scanf(xbt
, "control", "sysrq", "%c", &sysrq_key
)) {
210 printk(KERN_ERR
"Unable to read sysrq code in "
212 xenbus_transaction_end(xbt
, 1);
216 if (sysrq_key
!= '\0')
217 xenbus_printf(xbt
, "control", "sysrq", "%c", '\0');
219 err
= xenbus_transaction_end(xbt
, 0);
223 if (sysrq_key
!= '\0')
224 handle_sysrq(sysrq_key
, NULL
);
227 static struct xenbus_watch shutdown_watch
= {
228 .node
= "control/shutdown",
229 .callback
= shutdown_handler
232 static struct xenbus_watch sysrq_watch
= {
233 .node
= "control/sysrq",
234 .callback
= sysrq_handler
237 static int setup_shutdown_watcher(void)
241 err
= register_xenbus_watch(&shutdown_watch
);
243 printk(KERN_ERR
"Failed to set shutdown watcher\n");
247 err
= register_xenbus_watch(&sysrq_watch
);
249 printk(KERN_ERR
"Failed to set sysrq watcher\n");
256 static int shutdown_event(struct notifier_block
*notifier
,
260 setup_shutdown_watcher();
264 static int __init
setup_shutdown_event(void)
266 static struct notifier_block xenstore_notifier
= {
267 .notifier_call
= shutdown_event
269 register_xenstore_notifier(&xenstore_notifier
);
274 subsys_initcall(setup_shutdown_event
);