Add power cycle support (-c) to shutdown.

Sponsored by: Netflix
This commit is contained in:
Warner Losh 2017-10-25 15:30:30 +00:00
parent dae8f61f5b
commit e60baa7252
2 changed files with 35 additions and 11 deletions

View File

@ -28,7 +28,7 @@
.\" @(#)shutdown.8 8.2 (Berkeley) 4/27/95
.\" $FreeBSD$
.\"
.Dd September 21, 2016
.Dd October 23, 2017
.Dt SHUTDOWN 8
.Os
.Sh NAME
@ -39,7 +39,7 @@
.Nm
.Op Fl
.Oo
.Fl h | Fl p |
.Fl c | Fl h | Fl p |
.Fl r | Fl k
.Oc
.Oo
@ -59,12 +59,22 @@ would otherwise not bother with such niceties.
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl c
The system is power cycled (power turned off and then back on)
at the specified time.
If the hardware doesn't support power cycle, the system will be
halted.
At the present time, only systems with BMC supported by the
.Xr ipmi 4
driver that implement this functionality support this flag.
The amount of time the system is off is dependent on the device
that implements this feature.
.It Fl h
The system is halted at the specified
.Ar time .
.It Fl p
The system is halted and the power is turned off
(hardware support required)
(hardware support required, otherwise the system is halted)
at the specified
.Ar time .
.It Fl r
@ -79,6 +89,7 @@ does not actually halt the system, but leaves the
system multi-user with logins disabled (for all but super-user).
.It Fl o
If one of the
.Fl c ,
.Fl h ,
.Fl p
or

View File

@ -89,7 +89,7 @@ static struct interval {
#undef S
static time_t offset, shuttime;
static int dohalt, dopower, doreboot, killflg, mbuflen, oflag;
static int docycle, dohalt, dopower, doreboot, killflg, mbuflen, oflag;
static char mbuf[BUFSIZ];
static const char *nosync, *whom;
@ -141,11 +141,14 @@ main(int argc, char **argv)
goto poweroff;
}
while ((ch = getopt(argc, argv, "-hknopr")) != -1)
while ((ch = getopt(argc, argv, "-chknopr")) != -1)
switch (ch) {
case '-':
readstdin = 1;
break;
case 'c':
docycle = 1;
break;
case 'h':
dohalt = 1;
break;
@ -174,11 +177,11 @@ main(int argc, char **argv)
if (argc < 1)
usage((char *)NULL);
if (killflg + doreboot + dohalt + dopower > 1)
usage("incompatible switches -h, -k, -p and -r");
if (killflg + doreboot + dohalt + dopower + docycle > 1)
usage("incompatible switches -c, -h, -k, -p and -r");
if (oflag && !(dohalt || dopower || doreboot))
usage("-o requires -h, -p or -r");
if (oflag && !(dohalt || dopower || doreboot || docycle))
usage("-o requires -c, -h, -p or -r");
if (nosync != NULL && !oflag)
usage("-n requires -o");
@ -356,8 +359,8 @@ die_you_gravy_sucking_pig_dog(void)
char *empty_environ[] = { NULL };
syslog(LOG_NOTICE, "%s by %s: %s",
doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" :
"shutdown", whom, mbuf);
doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" :
docycle ? "power-cycle" : "shutdown", whom, mbuf);
(void)printf("\r\nSystem shutdown time has arrived\007\007\r\n");
if (killflg) {
@ -367,6 +370,8 @@ die_you_gravy_sucking_pig_dog(void)
#ifdef DEBUG
if (doreboot)
(void)printf("reboot");
else if (docycle)
(void)printf("power-cycle");
else if (dohalt)
(void)printf("halt");
else if (dopower)
@ -379,6 +384,7 @@ die_you_gravy_sucking_pig_dog(void)
(void)kill(1, doreboot ? SIGINT : /* reboot */
dohalt ? SIGUSR1 : /* halt */
dopower ? SIGUSR2 : /* power-down */
docycle ? SIGWINCH : /* power-cycle */
SIGTERM); /* single-user */
} else {
if (doreboot) {
@ -402,6 +408,13 @@ die_you_gravy_sucking_pig_dog(void)
_PATH_HALT);
warn(_PATH_HALT);
}
else if (docycle) {
execle(_PATH_HALT, "halt", "-l", "-c", nosync,
(char *)NULL, empty_environ);
syslog(LOG_ERR, "shutdown: can't exec %s: %m.",
_PATH_HALT);
warn(_PATH_HALT);
}
(void)kill(1, SIGTERM); /* to single-user */
}
#endif