Skip to content

Commit

Permalink
xen: do not respond to unknown xenstore control requests
Browse files Browse the repository at this point in the history
The PV xenbus control/shutdown node is written by the toolstack as a
request to the guest to perform a particular action (shutdown, reboot,
suspend etc). The guest is expected to acknowledge that it will
complete a request by clearing the control node.

Previously it would acknowledge any request, even if it did not know
what to do with it. Specifically in the case where CONFIG_PM_SLEEP is
not enabled the kernel would acknowledge a suspend request even though
it was not actually going to do anything.

Instead make the kernel only acknowledge requests if it is actually
going to do something with it. This will improve the toolstack's
ability to diagnose and deal with failures.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
  • Loading branch information
Ian Campbell authored and Stefano Stabellini committed Feb 25, 2011
1 parent e057a4b commit 5527172
Showing 1 changed file with 37 additions and 12 deletions.
49 changes: 37 additions & 12 deletions drivers/xen/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,12 +172,39 @@ static void do_suspend(void)
}
#endif /* CONFIG_PM_SLEEP */

struct shutdown_handler {
const char *command;
void (*cb)(void);
};

static void do_poweroff(void)
{
shutting_down = SHUTDOWN_POWEROFF;
orderly_poweroff(false);
}

static void do_reboot(void)
{
shutting_down = SHUTDOWN_POWEROFF; /* ? */
ctrl_alt_del();
}

static void shutdown_handler(struct xenbus_watch *watch,
const char **vec, unsigned int len)
{
char *str;
struct xenbus_transaction xbt;
int err;
static struct shutdown_handler handlers[] = {
{ "poweroff", do_poweroff },
{ "halt", do_poweroff },
{ "reboot", do_reboot },
#ifdef CONFIG_PM_SLEEP
{ "suspend", do_suspend },
#endif
{NULL, NULL},
};
static struct shutdown_handler *handler;

if (shutting_down != SHUTDOWN_INVALID)
return;
Expand All @@ -194,25 +221,23 @@ static void shutdown_handler(struct xenbus_watch *watch,
return;
}

xenbus_write(xbt, "control", "shutdown", "");
for (handler = &handlers[0]; handler->command; handler++) {
if (strcmp(str, handler->command) == 0)
break;
}

/* Only acknowledge commands which we are prepared to handle. */
if (handler->cb)
xenbus_write(xbt, "control", "shutdown", "");

err = xenbus_transaction_end(xbt, 0);
if (err == -EAGAIN) {
kfree(str);
goto again;
}

if (strcmp(str, "poweroff") == 0 ||
strcmp(str, "halt") == 0) {
shutting_down = SHUTDOWN_POWEROFF;
orderly_poweroff(false);
} else if (strcmp(str, "reboot") == 0) {
shutting_down = SHUTDOWN_POWEROFF; /* ? */
ctrl_alt_del();
#ifdef CONFIG_PM_SLEEP
} else if (strcmp(str, "suspend") == 0) {
do_suspend();
#endif
if (handler->cb) {
handler->cb();
} else {
printk(KERN_INFO "Ignoring shutdown request: %s\n", str);
shutting_down = SHUTDOWN_INVALID;
Expand Down

0 comments on commit 5527172

Please sign in to comment.