Merge tag 'for-linus-20140507' of git://git.infradead.org/linux-mtd
[cascardo/linux.git] / drivers / xen / manage.c
index fc6c94c..32f9236 100644 (file)
@@ -198,10 +198,32 @@ struct shutdown_handler {
        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)
 {
-       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)
@@ -307,6 +329,10 @@ static struct xenbus_watch shutdown_watch = {
        .callback = shutdown_handler
 };
 
+static struct notifier_block xen_reboot_nb = {
+       .notifier_call = poweroff_nb,
+};
+
 static int setup_shutdown_watcher(void)
 {
        int err;
@@ -317,6 +343,7 @@ static int setup_shutdown_watcher(void)
                return err;
        }
 
+
 #ifdef CONFIG_MAGIC_SYSRQ
        err = register_xenbus_watch(&sysrq_watch);
        if (err) {
@@ -345,6 +372,7 @@ int xen_setup_shutdown_event(void)
        if (!xen_domain())
                return -ENODEV;
        register_xenstore_notifier(&xenstore_notifier);
+       register_reboot_notifier(&xen_reboot_nb);
 
        return 0;
 }