| halt: add a -k kexec flag |
| |
| --- a/man/halt.8 |
| +++ b/man/halt.8 |
| @@ -40,6 +40,7 @@ halt, reboot, poweroff \- stop the system. |
| .RB [ \-d ] |
| .RB [ \-f ] |
| .RB [ \-i ] |
| +.RB [ \-k ] |
| .br |
| .B /sbin/poweroff |
| .RB [ \-n ] |
| @@ -83,6 +84,8 @@ Put all hard drives on the system in stand-by mode just before halt or power-off |
| .IP \fB\-p\fP |
| When halting the system, switch off the power. This is the default when halt is |
| called as \fBpoweroff\fP. |
| +.IP \fB\-k\fP |
| +Try to reboot using \fBkexec\fP, if kernel supports it. |
| .\"}}} |
| .\"{{{ Diagnostics |
| .SH DIAGNOSTICS |
| --- a/src/halt.c |
| +++ b/src/halt.c |
| @@ -8,7 +8,7 @@ |
| * execute an "shutdown -r". This is for compatibility with |
| * sysvinit 2.4. |
| * |
| - * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p] |
| + * Usage: halt [-n] [-w] [-d] [-f] [-h] [-i] [-p] [-k] |
| * -n: don't sync before halting the system |
| * -w: only write a wtmp reboot record and exit. |
| * -d: don't write a wtmp record. |
| @@ -16,6 +16,7 @@ |
| * -h: put harddisks in standby mode |
| * -i: shut down all network interfaces. |
| * -p: power down the system (if possible, otherwise halt). |
| + * -k: reboot the system using kexec. |
| * |
| * Reboot and halt are both this program. Reboot |
| * is just a link to halt. Invoking the program |
| @@ -74,8 +75,10 @@ extern void write_wtmp(char *user, char *id, int pid, int type, char *line); |
| */ |
| void usage(void) |
| { |
| - fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s\n", |
| - progname, strcmp(progname, "halt") ? "" : " [-p]"); |
| + fprintf(stderr, "usage: %s [-n] [-w] [-d] [-f] [-h] [-i]%s%s\n", |
| + progname, |
| + strcmp(progname, "halt") ? "" : " [-p]", |
| + strcmp(progname, "reboot") ? "" : " [-k]"); |
| fprintf(stderr, "\t-n: don't sync before halting the system\n"); |
| fprintf(stderr, "\t-w: only write a wtmp reboot record and exit.\n"); |
| fprintf(stderr, "\t-d: don't write a wtmp record.\n"); |
| @@ -84,6 +87,8 @@ void usage(void) |
| fprintf(stderr, "\t-i: shut down all network interfaces.\n"); |
| if (!strcmp(progname, "halt")) |
| fprintf(stderr, "\t-p: power down the system (if possible, otherwise halt).\n"); |
| + if (!strcmp(progname, "reboot")) |
| + fprintf(stderr, "\t-k: reboot the system using kexec.\n"); |
| exit(1); |
| } |
| |
| @@ -182,6 +187,7 @@ int main(int argc, char **argv) |
| int do_ifdown = 0; |
| int do_hddown = 0; |
| int do_poweroff = 0; |
| + int do_kexec = 0; |
| int c; |
| char *tm = NULL; |
| |
| @@ -201,7 +207,7 @@ int main(int argc, char **argv) |
| /* |
| * Get flags |
| */ |
| - while((c = getopt(argc, argv, ":ihdfnpwt:")) != EOF) { |
| + while((c = getopt(argc, argv, ":ihdfnpwkt:")) != EOF) { |
| switch(c) { |
| case 'n': |
| do_sync = 0; |
| @@ -225,6 +231,9 @@ int main(int argc, char **argv) |
| case 'p': |
| do_poweroff = 1; |
| break; |
| + case 'k': |
| + do_kexec = 1; |
| + break; |
| case 't': |
| tm = optarg; |
| break; |
| @@ -242,10 +251,24 @@ int main(int argc, char **argv) |
| (void)chdir("/"); |
| |
| if (!do_hard && !do_nothing) { |
| + c = get_runlevel(); |
| + |
| + /* |
| + * We can't reboot using kexec through this path. |
| + */ |
| + if (c != '6' && do_reboot && do_kexec) { |
| + fprintf(stderr, "ERROR: using -k at this" |
| + " runlevel requires also -f\n" |
| + " (You probably want instead to reboot" |
| + " normally and let your reboot\n" |
| + " script, usually /etc/init.d/reboot," |
| + " specify -k)\n"); |
| + exit(1); |
| + } |
| + |
| /* |
| * See if we are in runlevel 0 or 6. |
| */ |
| - c = get_runlevel(); |
| if (c != '0' && c != '6') |
| do_shutdown(do_reboot ? "-r" : "-h", tm); |
| } |
| @@ -277,6 +300,15 @@ int main(int argc, char **argv) |
| if (do_nothing) exit(0); |
| |
| if (do_reboot) { |
| + /* |
| + * kexec or reboot |
| + */ |
| + if (do_kexec) |
| + init_reboot(BMAGIC_KEXEC); |
| + |
| + /* |
| + * Fall through if failed |
| + */ |
| init_reboot(BMAGIC_REBOOT); |
| } else { |
| /* |
| --- a/src/reboot.h |
| +++ b/src/reboot.h |
| @@ -47,5 +47,8 @@ |
| # define BMAGIC_POWEROFF BMAGIC_HALT |
| #endif |
| |
| +/* for kexec support */ |
| +#define BMAGIC_KEXEC 0x45584543 |
| + |
| #define init_reboot(magic) reboot(magic) |
| |