Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44b3c7af authored by Juergen Gross's avatar Juergen Gross Committed by David Vrabel
Browse files

xenbus: advertise control feature flags



The Xen docs specify several flags which a guest can set to advertise
which values of the xenstore control/shutdown key it will recognize.
This patch adds code to write all the relevant feature-flag keys.

Based-on-patch-by: default avatarPaul Durrant <paul.durrant@citrix.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
Reviewed-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
Reviewed-by: default avatarPaul Durrant <paul.durrant@citrix.com>
Signed-off-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
parent a6a198bc
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -168,7 +168,9 @@ static void do_suspend(void)
#endif	/* CONFIG_HIBERNATE_CALLBACKS */

struct shutdown_handler {
	const char *command;
#define SHUTDOWN_CMD_SIZE 11
	const char command[SHUTDOWN_CMD_SIZE];
	bool flag;
	void (*cb)(void);
};

@@ -206,22 +208,22 @@ static void do_reboot(void)
	ctrl_alt_del();
}

static struct shutdown_handler shutdown_handlers[] = {
	{ "poweroff",	true,	do_poweroff },
	{ "halt",	false,	do_poweroff },
	{ "reboot",	true,	do_reboot   },
#ifdef CONFIG_HIBERNATE_CALLBACKS
	{ "suspend",	true,	do_suspend  },
#endif
};

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_HIBERNATE_CALLBACKS
		{ "suspend",	do_suspend  },
#endif
		{NULL, NULL},
	};
	static struct shutdown_handler *handler;
	int idx;

	if (shutting_down != SHUTDOWN_INVALID)
		return;
@@ -238,13 +240,13 @@ static void shutdown_handler(struct xenbus_watch *watch,
		return;
	}

	for (handler = &handlers[0]; handler->command; handler++) {
		if (strcmp(str, handler->command) == 0)
	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
		if (strcmp(str, shutdown_handlers[idx].command) == 0)
			break;
	}

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

	err = xenbus_transaction_end(xbt, 0);
@@ -253,8 +255,8 @@ static void shutdown_handler(struct xenbus_watch *watch,
		goto again;
	}

	if (handler->cb) {
		handler->cb();
	if (idx < ARRAY_SIZE(shutdown_handlers)) {
		shutdown_handlers[idx].cb();
	} else {
		pr_info("Ignoring shutdown request: %s\n", str);
		shutting_down = SHUTDOWN_INVALID;
@@ -310,6 +312,9 @@ static struct notifier_block xen_reboot_nb = {
static int setup_shutdown_watcher(void)
{
	int err;
	int idx;
#define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
	char node[FEATURE_PATH_SIZE];

	err = register_xenbus_watch(&shutdown_watch);
	if (err) {
@@ -326,6 +331,14 @@ static int setup_shutdown_watcher(void)
	}
#endif

	for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
		if (!shutdown_handlers[idx].flag)
			continue;
		snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
			 shutdown_handlers[idx].command);
		xenbus_printf(XBT_NIL, "control", node, "%u", 1);
	}

	return 0;
}