Skip to content

Commit 44b3c7a

Browse files
jgross1David Vrabel
authored andcommitted
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: Paul Durrant <[email protected]> Signed-off-by: Juergen Gross <[email protected]> Reviewed-by: David Vrabel <[email protected]> Reviewed-by: Paul Durrant <[email protected]> Signed-off-by: David Vrabel <[email protected]>
1 parent a6a198b commit 44b3c7a

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

drivers/xen/manage.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,9 @@ static void do_suspend(void)
168168
#endif /* CONFIG_HIBERNATE_CALLBACKS */
169169

170170
struct shutdown_handler {
171-
const char *command;
171+
#define SHUTDOWN_CMD_SIZE 11
172+
const char command[SHUTDOWN_CMD_SIZE];
173+
bool flag;
172174
void (*cb)(void);
173175
};
174176

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

211+
static struct shutdown_handler shutdown_handlers[] = {
212+
{ "poweroff", true, do_poweroff },
213+
{ "halt", false, do_poweroff },
214+
{ "reboot", true, do_reboot },
215+
#ifdef CONFIG_HIBERNATE_CALLBACKS
216+
{ "suspend", true, do_suspend },
217+
#endif
218+
};
219+
209220
static void shutdown_handler(struct xenbus_watch *watch,
210221
const char **vec, unsigned int len)
211222
{
212223
char *str;
213224
struct xenbus_transaction xbt;
214225
int err;
215-
static struct shutdown_handler handlers[] = {
216-
{ "poweroff", do_poweroff },
217-
{ "halt", do_poweroff },
218-
{ "reboot", do_reboot },
219-
#ifdef CONFIG_HIBERNATE_CALLBACKS
220-
{ "suspend", do_suspend },
221-
#endif
222-
{NULL, NULL},
223-
};
224-
static struct shutdown_handler *handler;
226+
int idx;
225227

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

241-
for (handler = &handlers[0]; handler->command; handler++) {
242-
if (strcmp(str, handler->command) == 0)
243+
for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
244+
if (strcmp(str, shutdown_handlers[idx].command) == 0)
243245
break;
244246
}
245247

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

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

256-
if (handler->cb) {
257-
handler->cb();
258+
if (idx < ARRAY_SIZE(shutdown_handlers)) {
259+
shutdown_handlers[idx].cb();
258260
} else {
259261
pr_info("Ignoring shutdown request: %s\n", str);
260262
shutting_down = SHUTDOWN_INVALID;
@@ -310,6 +312,9 @@ static struct notifier_block xen_reboot_nb = {
310312
static int setup_shutdown_watcher(void)
311313
{
312314
int err;
315+
int idx;
316+
#define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
317+
char node[FEATURE_PATH_SIZE];
313318

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

334+
for (idx = 0; idx < ARRAY_SIZE(shutdown_handlers); idx++) {
335+
if (!shutdown_handlers[idx].flag)
336+
continue;
337+
snprintf(node, FEATURE_PATH_SIZE, "feature-%s",
338+
shutdown_handlers[idx].command);
339+
xenbus_printf(XBT_NIL, "control", node, "%u", 1);
340+
}
341+
329342
return 0;
330343
}
331344

0 commit comments

Comments
 (0)