@@ -168,7 +168,9 @@ static void do_suspend(void)
168
168
#endif /* CONFIG_HIBERNATE_CALLBACKS */
169
169
170
170
struct shutdown_handler {
171
- const char * command ;
171
+ #define SHUTDOWN_CMD_SIZE 11
172
+ const char command [SHUTDOWN_CMD_SIZE ];
173
+ bool flag ;
172
174
void (* cb )(void );
173
175
};
174
176
@@ -206,22 +208,22 @@ static void do_reboot(void)
206
208
ctrl_alt_del ();
207
209
}
208
210
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
+
209
220
static void shutdown_handler (struct xenbus_watch * watch ,
210
221
const char * * vec , unsigned int len )
211
222
{
212
223
char * str ;
213
224
struct xenbus_transaction xbt ;
214
225
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 ;
225
227
226
228
if (shutting_down != SHUTDOWN_INVALID )
227
229
return ;
@@ -238,13 +240,13 @@ static void shutdown_handler(struct xenbus_watch *watch,
238
240
return ;
239
241
}
240
242
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 )
243
245
break ;
244
246
}
245
247
246
248
/* Only acknowledge commands which we are prepared to handle. */
247
- if (handler -> cb )
249
+ if (idx < ARRAY_SIZE ( shutdown_handlers ) )
248
250
xenbus_write (xbt , "control" , "shutdown" , "" );
249
251
250
252
err = xenbus_transaction_end (xbt , 0 );
@@ -253,8 +255,8 @@ static void shutdown_handler(struct xenbus_watch *watch,
253
255
goto again ;
254
256
}
255
257
256
- if (handler -> cb ) {
257
- handler -> cb ();
258
+ if (idx < ARRAY_SIZE ( shutdown_handlers ) ) {
259
+ shutdown_handlers [ idx ]. cb ();
258
260
} else {
259
261
pr_info ("Ignoring shutdown request: %s\n" , str );
260
262
shutting_down = SHUTDOWN_INVALID ;
@@ -310,6 +312,9 @@ static struct notifier_block xen_reboot_nb = {
310
312
static int setup_shutdown_watcher (void )
311
313
{
312
314
int err ;
315
+ int idx ;
316
+ #define FEATURE_PATH_SIZE (SHUTDOWN_CMD_SIZE + sizeof("feature-"))
317
+ char node [FEATURE_PATH_SIZE ];
313
318
314
319
err = register_xenbus_watch (& shutdown_watch );
315
320
if (err ) {
@@ -326,6 +331,14 @@ static int setup_shutdown_watcher(void)
326
331
}
327
332
#endif
328
333
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
+
329
342
return 0 ;
330
343
}
331
344
0 commit comments