|
@@ -198,10 +198,32 @@ struct shutdown_handler {
|
|
void (*cb)(void);
|
|
void (*cb)(void);
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
|
|
|
|
+{
|
|
|
|
+ switch (code) {
|
|
|
|
+ case SYS_DOWN:
|
|
|
|
+ case SYS_HALT:
|
|
|
|
+ case SYS_POWER_OFF:
|
|
|
|
+ shutting_down = SHUTDOWN_POWEROFF;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return NOTIFY_DONE;
|
|
|
|
+}
|
|
static void do_poweroff(void)
|
|
static void do_poweroff(void)
|
|
{
|
|
{
|
|
- shutting_down = SHUTDOWN_POWEROFF;
|
|
|
|
- orderly_poweroff(false);
|
|
|
|
|
|
+ switch (system_state) {
|
|
|
|
+ case SYSTEM_BOOTING:
|
|
|
|
+ orderly_poweroff(true);
|
|
|
|
+ break;
|
|
|
|
+ case SYSTEM_RUNNING:
|
|
|
|
+ orderly_poweroff(false);
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ /* Don't do it when we are halting/rebooting. */
|
|
|
|
+ pr_info("Ignoring Xen toolstack shutdown.\n");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void do_reboot(void)
|
|
static void do_reboot(void)
|
|
@@ -307,6 +329,10 @@ static struct xenbus_watch shutdown_watch = {
|
|
.callback = shutdown_handler
|
|
.callback = shutdown_handler
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static struct notifier_block xen_reboot_nb = {
|
|
|
|
+ .notifier_call = poweroff_nb,
|
|
|
|
+};
|
|
|
|
+
|
|
static int setup_shutdown_watcher(void)
|
|
static int setup_shutdown_watcher(void)
|
|
{
|
|
{
|
|
int err;
|
|
int err;
|
|
@@ -317,6 +343,7 @@ static int setup_shutdown_watcher(void)
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+
|
|
#ifdef CONFIG_MAGIC_SYSRQ
|
|
#ifdef CONFIG_MAGIC_SYSRQ
|
|
err = register_xenbus_watch(&sysrq_watch);
|
|
err = register_xenbus_watch(&sysrq_watch);
|
|
if (err) {
|
|
if (err) {
|
|
@@ -345,6 +372,7 @@ int xen_setup_shutdown_event(void)
|
|
if (!xen_domain())
|
|
if (!xen_domain())
|
|
return -ENODEV;
|
|
return -ENODEV;
|
|
register_xenstore_notifier(&xenstore_notifier);
|
|
register_xenstore_notifier(&xenstore_notifier);
|
|
|
|
+ register_reboot_notifier(&xen_reboot_nb);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|