This source file includes following definitions.
- emergency_restart
- kernel_restart_prepare
- register_reboot_notifier
- unregister_reboot_notifier
- devm_unregister_reboot_notifier
- devm_register_reboot_notifier
- register_restart_handler
- unregister_restart_handler
- do_kernel_restart
- migrate_to_reboot_cpu
- kernel_restart
- kernel_shutdown_prepare
- kernel_halt
- kernel_power_off
- SYSCALL_DEFINE4
- deferred_cad
- ctrl_alt_del
- run_cmd
- __orderly_reboot
- __orderly_poweroff
- poweroff_work_func
- orderly_poweroff
- reboot_work_func
- orderly_reboot
- reboot_setup
1
2
3
4
5
6
7
8 #define pr_fmt(fmt) "reboot: " fmt
9
10 #include <linux/ctype.h>
11 #include <linux/export.h>
12 #include <linux/kexec.h>
13 #include <linux/kmod.h>
14 #include <linux/kmsg_dump.h>
15 #include <linux/reboot.h>
16 #include <linux/suspend.h>
17 #include <linux/syscalls.h>
18 #include <linux/syscore_ops.h>
19 #include <linux/uaccess.h>
20
21
22
23
24
25 int C_A_D = 1;
26 struct pid *cad_pid;
27 EXPORT_SYMBOL(cad_pid);
28
29 #if defined(CONFIG_ARM) || defined(CONFIG_UNICORE32)
30 #define DEFAULT_REBOOT_MODE = REBOOT_HARD
31 #else
32 #define DEFAULT_REBOOT_MODE
33 #endif
34 enum reboot_mode reboot_mode DEFAULT_REBOOT_MODE;
35 enum reboot_mode panic_reboot_mode = REBOOT_UNDEFINED;
36
37
38
39
40
41
42
43
44 int reboot_default = 1;
45 int reboot_cpu;
46 enum reboot_type reboot_type = BOOT_ACPI;
47 int reboot_force;
48
49
50
51
52
53 void (*pm_power_off_prepare)(void);
54 EXPORT_SYMBOL_GPL(pm_power_off_prepare);
55
56
57
58
59
60
61
62
63
64 void emergency_restart(void)
65 {
66 kmsg_dump(KMSG_DUMP_EMERG);
67 machine_emergency_restart();
68 }
69 EXPORT_SYMBOL_GPL(emergency_restart);
70
71 void kernel_restart_prepare(char *cmd)
72 {
73 blocking_notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);
74 system_state = SYSTEM_RESTART;
75 usermodehelper_disable();
76 device_shutdown();
77 }
78
79
80
81
82
83
84
85
86
87
88
89 int register_reboot_notifier(struct notifier_block *nb)
90 {
91 return blocking_notifier_chain_register(&reboot_notifier_list, nb);
92 }
93 EXPORT_SYMBOL(register_reboot_notifier);
94
95
96
97
98
99
100
101
102
103
104 int unregister_reboot_notifier(struct notifier_block *nb)
105 {
106 return blocking_notifier_chain_unregister(&reboot_notifier_list, nb);
107 }
108 EXPORT_SYMBOL(unregister_reboot_notifier);
109
110 static void devm_unregister_reboot_notifier(struct device *dev, void *res)
111 {
112 WARN_ON(unregister_reboot_notifier(*(struct notifier_block **)res));
113 }
114
115 int devm_register_reboot_notifier(struct device *dev, struct notifier_block *nb)
116 {
117 struct notifier_block **rcnb;
118 int ret;
119
120 rcnb = devres_alloc(devm_unregister_reboot_notifier,
121 sizeof(*rcnb), GFP_KERNEL);
122 if (!rcnb)
123 return -ENOMEM;
124
125 ret = register_reboot_notifier(nb);
126 if (!ret) {
127 *rcnb = nb;
128 devres_add(dev, rcnb);
129 } else {
130 devres_free(rcnb);
131 }
132
133 return ret;
134 }
135 EXPORT_SYMBOL(devm_register_reboot_notifier);
136
137
138
139
140
141 static ATOMIC_NOTIFIER_HEAD(restart_handler_list);
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181 int register_restart_handler(struct notifier_block *nb)
182 {
183 return atomic_notifier_chain_register(&restart_handler_list, nb);
184 }
185 EXPORT_SYMBOL(register_restart_handler);
186
187
188
189
190
191
192
193
194
195
196 int unregister_restart_handler(struct notifier_block *nb)
197 {
198 return atomic_notifier_chain_unregister(&restart_handler_list, nb);
199 }
200 EXPORT_SYMBOL(unregister_restart_handler);
201
202
203
204
205
206
207
208
209
210
211
212
213 void do_kernel_restart(char *cmd)
214 {
215 atomic_notifier_call_chain(&restart_handler_list, reboot_mode, cmd);
216 }
217
218 void migrate_to_reboot_cpu(void)
219 {
220
221 int cpu = reboot_cpu;
222
223 cpu_hotplug_disable();
224
225
226 if (!cpu_online(cpu))
227 cpu = cpumask_first(cpu_online_mask);
228
229
230 current->flags |= PF_NO_SETAFFINITY;
231
232
233 set_cpus_allowed_ptr(current, cpumask_of(cpu));
234 }
235
236
237
238
239
240
241
242
243
244 void kernel_restart(char *cmd)
245 {
246 kernel_restart_prepare(cmd);
247 migrate_to_reboot_cpu();
248 syscore_shutdown();
249 if (!cmd)
250 pr_emerg("Restarting system\n");
251 else
252 pr_emerg("Restarting system with command '%s'\n", cmd);
253 kmsg_dump(KMSG_DUMP_RESTART);
254 machine_restart(cmd);
255 }
256 EXPORT_SYMBOL_GPL(kernel_restart);
257
258 static void kernel_shutdown_prepare(enum system_states state)
259 {
260 blocking_notifier_call_chain(&reboot_notifier_list,
261 (state == SYSTEM_HALT) ? SYS_HALT : SYS_POWER_OFF, NULL);
262 system_state = state;
263 usermodehelper_disable();
264 device_shutdown();
265 }
266
267
268
269
270
271 void kernel_halt(void)
272 {
273 kernel_shutdown_prepare(SYSTEM_HALT);
274 migrate_to_reboot_cpu();
275 syscore_shutdown();
276 pr_emerg("System halted\n");
277 kmsg_dump(KMSG_DUMP_HALT);
278 machine_halt();
279 }
280 EXPORT_SYMBOL_GPL(kernel_halt);
281
282
283
284
285
286
287 void kernel_power_off(void)
288 {
289 kernel_shutdown_prepare(SYSTEM_POWER_OFF);
290 if (pm_power_off_prepare)
291 pm_power_off_prepare();
292 migrate_to_reboot_cpu();
293 syscore_shutdown();
294 pr_emerg("Power down\n");
295 kmsg_dump(KMSG_DUMP_POWEROFF);
296 machine_power_off();
297 }
298 EXPORT_SYMBOL_GPL(kernel_power_off);
299
300 DEFINE_MUTEX(system_transition_mutex);
301
302
303
304
305
306
307
308
309
310 SYSCALL_DEFINE4(reboot, int, magic1, int, magic2, unsigned int, cmd,
311 void __user *, arg)
312 {
313 struct pid_namespace *pid_ns = task_active_pid_ns(current);
314 char buffer[256];
315 int ret = 0;
316
317
318 if (!ns_capable(pid_ns->user_ns, CAP_SYS_BOOT))
319 return -EPERM;
320
321
322 if (magic1 != LINUX_REBOOT_MAGIC1 ||
323 (magic2 != LINUX_REBOOT_MAGIC2 &&
324 magic2 != LINUX_REBOOT_MAGIC2A &&
325 magic2 != LINUX_REBOOT_MAGIC2B &&
326 magic2 != LINUX_REBOOT_MAGIC2C))
327 return -EINVAL;
328
329
330
331
332
333
334 ret = reboot_pid_ns(pid_ns, cmd);
335 if (ret)
336 return ret;
337
338
339
340
341 if ((cmd == LINUX_REBOOT_CMD_POWER_OFF) && !pm_power_off)
342 cmd = LINUX_REBOOT_CMD_HALT;
343
344 mutex_lock(&system_transition_mutex);
345 switch (cmd) {
346 case LINUX_REBOOT_CMD_RESTART:
347 kernel_restart(NULL);
348 break;
349
350 case LINUX_REBOOT_CMD_CAD_ON:
351 C_A_D = 1;
352 break;
353
354 case LINUX_REBOOT_CMD_CAD_OFF:
355 C_A_D = 0;
356 break;
357
358 case LINUX_REBOOT_CMD_HALT:
359 kernel_halt();
360 do_exit(0);
361 panic("cannot halt");
362
363 case LINUX_REBOOT_CMD_POWER_OFF:
364 kernel_power_off();
365 do_exit(0);
366 break;
367
368 case LINUX_REBOOT_CMD_RESTART2:
369 ret = strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1);
370 if (ret < 0) {
371 ret = -EFAULT;
372 break;
373 }
374 buffer[sizeof(buffer) - 1] = '\0';
375
376 kernel_restart(buffer);
377 break;
378
379 #ifdef CONFIG_KEXEC_CORE
380 case LINUX_REBOOT_CMD_KEXEC:
381 ret = kernel_kexec();
382 break;
383 #endif
384
385 #ifdef CONFIG_HIBERNATION
386 case LINUX_REBOOT_CMD_SW_SUSPEND:
387 ret = hibernate();
388 break;
389 #endif
390
391 default:
392 ret = -EINVAL;
393 break;
394 }
395 mutex_unlock(&system_transition_mutex);
396 return ret;
397 }
398
399 static void deferred_cad(struct work_struct *dummy)
400 {
401 kernel_restart(NULL);
402 }
403
404
405
406
407
408
409 void ctrl_alt_del(void)
410 {
411 static DECLARE_WORK(cad_work, deferred_cad);
412
413 if (C_A_D)
414 schedule_work(&cad_work);
415 else
416 kill_cad_pid(SIGINT, 1);
417 }
418
419 char poweroff_cmd[POWEROFF_CMD_PATH_LEN] = "/sbin/poweroff";
420 static const char reboot_cmd[] = "/sbin/reboot";
421
422 static int run_cmd(const char *cmd)
423 {
424 char **argv;
425 static char *envp[] = {
426 "HOME=/",
427 "PATH=/sbin:/bin:/usr/sbin:/usr/bin",
428 NULL
429 };
430 int ret;
431 argv = argv_split(GFP_KERNEL, cmd, NULL);
432 if (argv) {
433 ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);
434 argv_free(argv);
435 } else {
436 ret = -ENOMEM;
437 }
438
439 return ret;
440 }
441
442 static int __orderly_reboot(void)
443 {
444 int ret;
445
446 ret = run_cmd(reboot_cmd);
447
448 if (ret) {
449 pr_warn("Failed to start orderly reboot: forcing the issue\n");
450 emergency_sync();
451 kernel_restart(NULL);
452 }
453
454 return ret;
455 }
456
457 static int __orderly_poweroff(bool force)
458 {
459 int ret;
460
461 ret = run_cmd(poweroff_cmd);
462
463 if (ret && force) {
464 pr_warn("Failed to start orderly shutdown: forcing the issue\n");
465
466
467
468
469
470
471 emergency_sync();
472 kernel_power_off();
473 }
474
475 return ret;
476 }
477
478 static bool poweroff_force;
479
480 static void poweroff_work_func(struct work_struct *work)
481 {
482 __orderly_poweroff(poweroff_force);
483 }
484
485 static DECLARE_WORK(poweroff_work, poweroff_work_func);
486
487
488
489
490
491
492
493
494 void orderly_poweroff(bool force)
495 {
496 if (force)
497 poweroff_force = true;
498 schedule_work(&poweroff_work);
499 }
500 EXPORT_SYMBOL_GPL(orderly_poweroff);
501
502 static void reboot_work_func(struct work_struct *work)
503 {
504 __orderly_reboot();
505 }
506
507 static DECLARE_WORK(reboot_work, reboot_work_func);
508
509
510
511
512
513
514
515 void orderly_reboot(void)
516 {
517 schedule_work(&reboot_work);
518 }
519 EXPORT_SYMBOL_GPL(orderly_reboot);
520
521 static int __init reboot_setup(char *str)
522 {
523 for (;;) {
524 enum reboot_mode *mode;
525
526
527
528
529
530
531 reboot_default = 0;
532
533 if (!strncmp(str, "panic_", 6)) {
534 mode = &panic_reboot_mode;
535 str += 6;
536 } else {
537 mode = &reboot_mode;
538 }
539
540 switch (*str) {
541 case 'w':
542 *mode = REBOOT_WARM;
543 break;
544
545 case 'c':
546 *mode = REBOOT_COLD;
547 break;
548
549 case 'h':
550 *mode = REBOOT_HARD;
551 break;
552
553 case 's':
554 {
555 int rc;
556
557 if (isdigit(*(str+1))) {
558 rc = kstrtoint(str+1, 0, &reboot_cpu);
559 if (rc)
560 return rc;
561 } else if (str[1] == 'm' && str[2] == 'p' &&
562 isdigit(*(str+3))) {
563 rc = kstrtoint(str+3, 0, &reboot_cpu);
564 if (rc)
565 return rc;
566 } else
567 *mode = REBOOT_SOFT;
568 break;
569 }
570 case 'g':
571 *mode = REBOOT_GPIO;
572 break;
573
574 case 'b':
575 case 'a':
576 case 'k':
577 case 't':
578 case 'e':
579 case 'p':
580 reboot_type = *str;
581 break;
582
583 case 'f':
584 reboot_force = 1;
585 break;
586 }
587
588 str = strchr(str, ',');
589 if (str)
590 str++;
591 else
592 break;
593 }
594 return 1;
595 }
596 __setup("reboot=", reboot_setup);