aboutsummaryrefslogtreecommitdiff
path: root/sbin/shutdown
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2017-10-25 15:30:30 +0000
committerWarner Losh <imp@FreeBSD.org>2017-10-25 15:30:30 +0000
commite60baa725230ed256b04bfe82488ae46fa770a5c (patch)
treed390c9bd088ebebda8437d893e4ad4ee76aeb573 /sbin/shutdown
parentdae8f61f5b3fa041968d17f76bf691ea278ab838 (diff)
downloadsrc-e60baa725230ed256b04bfe82488ae46fa770a5c.tar.gz
src-e60baa725230ed256b04bfe82488ae46fa770a5c.zip
Add power cycle support (-c) to shutdown.
Sponsored by: Netflix
Notes
Notes: svn path=/head/; revision=324985
Diffstat (limited to 'sbin/shutdown')
-rw-r--r--sbin/shutdown/shutdown.817
-rw-r--r--sbin/shutdown/shutdown.c29
2 files changed, 35 insertions, 11 deletions
diff --git a/sbin/shutdown/shutdown.8 b/sbin/shutdown/shutdown.8
index 1b7c6e19bdf6..b388aaf92fe9 100644
--- a/sbin/shutdown/shutdown.8
+++ b/sbin/shutdown/shutdown.8
@@ -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
diff --git a/sbin/shutdown/shutdown.c b/sbin/shutdown/shutdown.c
index 6c24e4b2a580..7a878257a736 100644
--- a/sbin/shutdown/shutdown.c
+++ b/sbin/shutdown/shutdown.c
@@ -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