From b180c247da3427572377f1dda16026ceef181844 Mon Sep 17 00:00:00 2001 From: Apple Date: Thu, 3 Aug 2006 20:36:17 +0000 Subject: [PATCH] system_cmds-336.17.tar.gz --- at.tproj/Makefile.dist | 2 +- atrun.tproj/Makefile.dist | 2 +- atrun.tproj/atrun.8 | 2 +- getty.tproj/getty.8 | 2 +- getty.tproj/gettytab.5 | 2 +- getty.tproj/ttys.5 | 2 +- reboot.tproj/Makefile | 3 +- reboot.tproj/Makefile.preamble | 3 +- reboot.tproj/kextmanager.defs | 1 + reboot.tproj/reboot.8 | 8 ++- reboot.tproj/reboot.c | 95 ++++++++++++++++++++++++++- shutdown.tproj/Makefile | 3 +- shutdown.tproj/Makefile.preamble | 3 +- shutdown.tproj/kextmanager.defs | 1 + shutdown.tproj/shutdown.8 | 15 +++-- shutdown.tproj/shutdown.c | 106 +++++++++++++++++++++++++++++-- 16 files changed, 226 insertions(+), 24 deletions(-) create mode 100644 reboot.tproj/kextmanager.defs create mode 100644 shutdown.tproj/kextmanager.defs diff --git a/at.tproj/Makefile.dist b/at.tproj/Makefile.dist index bdfa515..1468a6c 100644 --- a/at.tproj/Makefile.dist +++ b/at.tproj/Makefile.dist @@ -1,4 +1,4 @@ -# $Id: Makefile.dist,v 1.1.1.1 1999/05/02 04:21:18 wsanchez Exp $ +# $Id: Makefile.dist,v 1.1 1999/05/02 04:21:18 wsanchez Exp $ PROG= at SRCS= at.c panic.c parsetime.c diff --git a/atrun.tproj/Makefile.dist b/atrun.tproj/Makefile.dist index 726a2e7..0980f04 100644 --- a/atrun.tproj/Makefile.dist +++ b/atrun.tproj/Makefile.dist @@ -1,4 +1,4 @@ -# $Id: Makefile.dist,v 1.1.1.1 1999/05/02 04:21:19 wsanchez Exp $ +# $Id: Makefile.dist,v 1.1 1999/05/02 04:21:19 wsanchez Exp $ PROG= atrun BINDIR= /usr/libexec diff --git a/atrun.tproj/atrun.8 b/atrun.tproj/atrun.8 index 7ebc04e..8d50f58 100644 --- a/atrun.tproj/atrun.8 +++ b/atrun.tproj/atrun.8 @@ -27,7 +27,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $Id: atrun.8,v 1.1.1.1 1999/05/02 04:21:19 wsanchez Exp $ +.\" $Id: atrun.8,v 1.1 1999/05/02 04:21:19 wsanchez Exp $ .\" .Dd December 5, 1993 .Dt ATRUN 8 diff --git a/getty.tproj/getty.8 b/getty.tproj/getty.8 index cc6612f..a97f053 100644 --- a/getty.tproj/getty.8 +++ b/getty.tproj/getty.8 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)getty.8 8.1 (Berkeley) 6/4/93 -.\" $Id: getty.8,v 1.1.1.1 1999/05/02 04:21:29 wsanchez Exp $ +.\" $Id: getty.8,v 1.1 1999/05/02 04:21:29 wsanchez Exp $ .\" .Dd June 4, 1993 .Dt GETTY 8 diff --git a/getty.tproj/gettytab.5 b/getty.tproj/gettytab.5 index 51d4cfe..38e9a96 100644 --- a/getty.tproj/gettytab.5 +++ b/getty.tproj/gettytab.5 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)gettytab.5 8.4 (Berkeley) 4/19/94 -.\" $Id: gettytab.5,v 1.1.1.1 1999/05/02 04:21:29 wsanchez Exp $ +.\" $Id: gettytab.5,v 1.1 1999/05/02 04:21:29 wsanchez Exp $ .\" .Dd April 19, 1994 .Dt GETTYTAB 5 diff --git a/getty.tproj/ttys.5 b/getty.tproj/ttys.5 index b2f6584..3a2fc45 100644 --- a/getty.tproj/ttys.5 +++ b/getty.tproj/ttys.5 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" from: @(#)ttys.5 8.1 (Berkeley) 6/4/93 -.\" $Id: ttys.5,v 1.1.1.1 1999/05/02 04:21:29 wsanchez Exp $ +.\" $Id: ttys.5,v 1.1 1999/05/02 04:21:29 wsanchez Exp $ .\" .Dd June 4, 1993 .Dt TTYS 5 diff --git a/reboot.tproj/Makefile b/reboot.tproj/Makefile index 74f27bc..804761c 100644 --- a/reboot.tproj/Makefile +++ b/reboot.tproj/Makefile @@ -13,10 +13,11 @@ PROJECTVERSION = 2.8 PROJECT_TYPE = Tool CFILES = reboot.c +DEFSFILES = kextmanager.defs OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\ boot_hp300.8 boot_i386.8 boot_sparc.8 boot_tahoe.8\ - boot_vax.8 reboot.8 + boot_vax.8 reboot.8 $(DEFSFILES) MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/reboot.tproj/Makefile.preamble b/reboot.tproj/Makefile.preamble index d5059b1..618870c 100644 --- a/reboot.tproj/Makefile.preamble +++ b/reboot.tproj/Makefile.preamble @@ -1,2 +1,3 @@ OTHER_GENERATED_OFILES = $(VERS_OFILE) - +OTHER_OFILES = kextmanagerUser.o +# OTHER_CFLAGS += -O0 diff --git a/reboot.tproj/kextmanager.defs b/reboot.tproj/kextmanager.defs new file mode 100644 index 0000000..2a77d65 --- /dev/null +++ b/reboot.tproj/kextmanager.defs @@ -0,0 +1 @@ +#include diff --git a/reboot.tproj/reboot.8 b/reboot.tproj/reboot.8 index 0569b72..46796be 100644 --- a/reboot.tproj/reboot.8 +++ b/reboot.tproj/reboot.8 @@ -41,7 +41,7 @@ .Nd stopping and restarting the system .Sh SYNOPSIS .Nm halt -.Op Fl lnq +.Op Fl lnqu .Nm .Op Fl lnq .Sh DESCRIPTION @@ -83,6 +83,12 @@ the flushing of the file system cache is performed (if the .Fl n option is not specified). This option should probably not be used. +.It Fl u +The system is halted up until the point of removing system power, but waits +before removing power for 5 minutes so that an external UPS +(uninterruptible power supply) can forcibly remove power. +This simulates a dirty shutdown to permit a later automatic power on. OS X uses +this mode automatically with supported UPSs in emergency shutdowns. .El .Pp Normally, the diff --git a/reboot.tproj/reboot.c b/reboot.tproj/reboot.c index 61b6e38..f970ca5 100644 --- a/reboot.tproj/reboot.c +++ b/reboot.tproj/reboot.c @@ -60,8 +60,19 @@ static const char rcsid[] = #include #include +#ifdef __APPLE__ +#include "kextmanager.h" +#include +#include // allocate +#include // task_self, etc +#include // bootstrap +#endif + void usage(void); u_int get_pageins(void); +#ifdef __APPLE__ +int reserve_reboot(void); +#endif int dohalt; @@ -69,7 +80,7 @@ int main(int argc, char *argv[]) { struct passwd *pw; - int ch, howto, i, fd, kflag, lflag, nflag, qflag, pflag, sverrno; + int ch, howto, i, fd, kflag, lflag, nflag, qflag, pflag, uflag, sverrno; u_int pageins; char *kernel, *p; const char *user; @@ -83,7 +94,7 @@ main(int argc, char *argv[]) #ifndef __APPLE__ while ((ch = getopt(argc, argv, "dk:lnpq")) != -1) #else - while ((ch = getopt(argc, argv, "lnq")) != -1) + while ((ch = getopt(argc, argv, "lnqu")) != -1) #endif switch(ch) { #ifndef __APPLE__ @@ -109,6 +120,10 @@ main(int argc, char *argv[]) howto |= RB_POWEROFF; break; #endif + case 'u': + uflag = 1; + howto |= RB_UPSDELAY; + break; case 'q': qflag = 1; break; @@ -128,6 +143,13 @@ main(int argc, char *argv[]) err(1, NULL); } +#ifdef __APPLE__ + if (!lflag) { // shutdown(8) has already checked w/kextd + if ((errno = reserve_reboot()) && !qflag) + err(1, "couldn't lock for reboot"); + } +#endif + if (qflag) { reboot(howto); err(1, NULL); @@ -153,7 +175,8 @@ main(int argc, char *argv[]) pw->pw_name : "???"; if (dohalt) { openlog("halt", 0, LOG_AUTH | LOG_CONS); - syslog(LOG_CRIT, "halted by %s", user); + syslog(LOG_CRIT, "halted by %s%s", user, + (howto & RB_UPSDELAY) ? " with UPS delay":""); } else { openlog("reboot", 0, LOG_AUTH | LOG_CONS); syslog(LOG_CRIT, "rebooted by %s", user); @@ -216,7 +239,9 @@ main(int argc, char *argv[]) reboot(howto); /* FALLTHROUGH */ +#ifndef __APPLE__ restart: +#endif sverrno = errno; errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "", strerror(sverrno)); @@ -249,3 +274,67 @@ get_pageins() } return pageins; } + +#ifdef __APPLE__ +// XX another copy of this routine is in shutdown.c; it would be nice to share + +#define LCK_MAXTRIES 10 +#define LCK_DELAY 30 +/* + * contact kextd to lock for reboot + */ +int +reserve_reboot() +{ + int rval = ELAST+1; + kern_return_t macherr = KERN_FAILURE; + mach_port_t tport, bsport, kxport, myport = MACH_PORT_NULL; + int busyStatus, nretries = LCK_MAXTRIES; + dev_path_t busyDev = ""; + + // find kextd + tport = mach_task_self(); + if (tport == MACH_PORT_NULL) goto finish; + macherr = task_get_bootstrap_port(tport, &bsport); + if (macherr) goto finish; + macherr = bootstrap_look_up(bsport, KEXTD_SERVER_NAME, &kxport); + if (macherr) goto finish; + + // allocate a port to pass to kextd (in case we die) + macherr = mach_port_allocate(tport, MACH_PORT_RIGHT_RECEIVE, &myport); + if (macherr) goto finish; + + // loop trying to lock for reboot (i.e. no volumes are busy) + do { + nretries--; + macherr = kextmanager_lock_reboot(kxport, myport, busyDev, &busyStatus); + if (macherr) goto finish; + + if (busyStatus == EBUSY) { + if (*busyDev) { + warnx("%s is busy updating; delaying reboot (%d retries left)", + busyDev, nretries); + } else + warnx("kextd still starting up"); + if (nretries) sleep(LCK_DELAY); // don't sleep the last time + } + } while (busyStatus == EBUSY && nretries > 0); + + rval = busyStatus; + +finish: + if (macherr == BOOTSTRAP_UNKNOWN_SERVICE) { + mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); + rval = 0; + } else if (macherr) { + warnx("couldn't lock kext manager for reboot: %s", + mach_error_string(macherr)); + rval = ELAST + 1; + } + if (rval && myport != MACH_PORT_NULL) { + mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); + } + + return rval; +} +#endif diff --git a/shutdown.tproj/Makefile b/shutdown.tproj/Makefile index a257e8c..e0df19d 100644 --- a/shutdown.tproj/Makefile +++ b/shutdown.tproj/Makefile @@ -15,9 +15,10 @@ PROJECT_TYPE = Tool HFILES = pathnames.h CFILES = shutdown.c +DEFSFILES = kextmanager.defs OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\ - shutdown.8 + shutdown.8 $(DEFSFILES) MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles diff --git a/shutdown.tproj/Makefile.preamble b/shutdown.tproj/Makefile.preamble index d5059b1..618870c 100644 --- a/shutdown.tproj/Makefile.preamble +++ b/shutdown.tproj/Makefile.preamble @@ -1,2 +1,3 @@ OTHER_GENERATED_OFILES = $(VERS_OFILE) - +OTHER_OFILES = kextmanagerUser.o +# OTHER_CFLAGS += -O0 diff --git a/shutdown.tproj/kextmanager.defs b/shutdown.tproj/kextmanager.defs new file mode 100644 index 0000000..2a77d65 --- /dev/null +++ b/shutdown.tproj/kextmanager.defs @@ -0,0 +1 @@ +#include diff --git a/shutdown.tproj/shutdown.8 b/shutdown.tproj/shutdown.8 index fb2c1f7..12bd570 100644 --- a/shutdown.tproj/shutdown.8 +++ b/shutdown.tproj/shutdown.8 @@ -42,7 +42,9 @@ .Nm .Op Fl .Oo -.Fl h | +.Fl h +.Op Fl u +| .Fl r | Fl k .Oc .Oo @@ -75,9 +77,8 @@ option 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 h , -.Fl p +If +.Fl h or .Fl r is specified, @@ -98,6 +99,12 @@ option to or .Xr reboot 8 . This option should probably not be used. +.It Fl u +The system is halted up until the point of removing system power, but waits +before removing power for 5 minutes so that an external UPS +(uninterruptible power supply) can forcibly remove power. +This simulates a dirty shutdown to permit a later automatic power on. OS X uses +this mode automatically with supported UPSs in emergency shutdowns. .It Ar time .Ar Time is the time at which diff --git a/shutdown.tproj/shutdown.c b/shutdown.tproj/shutdown.c index dcef480..91ea293 100644 --- a/shutdown.tproj/shutdown.c +++ b/shutdown.tproj/shutdown.c @@ -65,6 +65,13 @@ static const char rcsid[] = #include #include +#ifdef __APPLE__ +#include "kextmanager.h" +#include +#include // allocate +#include // task_self, etc +#include // bootstrap +#endif #include "pathnames.h" @@ -102,7 +109,7 @@ struct interval { #undef S static time_t offset, shuttime; -static int dohalt, dopower, doreboot, killflg, mbuflen, oflag = 1; +static int dohalt, dopower, doreboot, doups, killflg, mbuflen, oflag = 1; static char mbuf[BUFSIZ]; static const char *nosync, *whom; @@ -120,6 +127,9 @@ void timeout(int); void timewarn(int); void usage(const char *); int audit_shutdown(int); +#ifdef __APPLE__ +int reserve_reboot(void); +#endif int main(argc, argv) @@ -139,7 +149,7 @@ main(argc, argv) #ifndef __APPLE__ while ((ch = getopt(argc, argv, "-hknopr")) != -1) #else - while ((ch = getopt(argc, argv, "-hknor")) != -1) + while ((ch = getopt(argc, argv, "-hknoru")) != -1) #endif switch (ch) { case '-': @@ -150,6 +160,7 @@ main(argc, argv) break; case 'k': killflg = 1; + oflag = 0; break; case 'n': nosync = "-n"; @@ -162,6 +173,9 @@ main(argc, argv) dopower = 1; break; #endif + case 'u': + doups = 1; + break; case 'r': doreboot = 1; break; @@ -187,6 +201,9 @@ main(argc, argv) if (oflag && !(dohalt || doreboot)) usage("-o requires -h or -r"); + + if (doups && !dohalt) + usage("-u requires -h"); #endif if (nosync != NULL && !oflag) @@ -378,13 +395,18 @@ die_you_gravy_sucking_pig_dog() { char *empty_environ[] = { NULL }; - syslog(LOG_NOTICE, "%s by %s: %s", +#ifdef __APPLE__ + if ((errno = reserve_reboot())) + err(1, "couldn't lock for reboot"); +#endif + + syslog(LOG_NOTICE, "%s%s by %s: %s", #ifndef __APPLE__ doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" : #else doreboot ? "reboot" : dohalt ? "halt" : #endif - "shutdown", whom, mbuf); + "shutdown", doups?"with UPS delay":"", whom, mbuf); #ifndef __APPLE__ (void)sleep(2); #endif @@ -433,7 +455,13 @@ die_you_gravy_sucking_pig_dog() warn(_PATH_REBOOT); } else if (dohalt) { - execle(_PATH_HALT, "halt", "-l", nosync, + char *halt_args; + if(doups) { + halt_args = "-lu"; + } else { + halt_args = "-l"; + } + execle(_PATH_HALT, "halt", halt_args, nosync, (char *)NULL, empty_environ); syslog(LOG_ERR, "shutdown: can't exec %s: %m.", _PATH_HALT); @@ -588,7 +616,7 @@ usage(cp) if (cp != NULL) warnx("%s", cp); (void)fprintf(stderr, - "usage: shutdown [-] [-h | -p | -r | -k] [-o [-n]]" + "usage: shutdown [-] [-h [-u] | -r | -k] [-o [-n]]" " time [warning-message ...]\n"); exit(1); } @@ -638,3 +666,69 @@ int audit_shutdown(int exitstatus) } return 1; } + + +#ifdef __APPLE__ +// XX copied from reboot.c; would be nice to share the code + +#define LCK_MAXTRIES 10 +#define LCK_DELAY 30 +/* + * contact kextd to lock for reboot + */ +int +reserve_reboot() +{ + int rval = ELAST+1; + kern_return_t macherr = KERN_FAILURE; + mach_port_t tport, bsport, kxport, myport = MACH_PORT_NULL; + int busyStatus, nretries = LCK_MAXTRIES; + dev_path_t busyDev = ""; + + // find kextd + tport = mach_task_self(); + if (tport == MACH_PORT_NULL) goto finish; + macherr = task_get_bootstrap_port(tport, &bsport); + if (macherr) goto finish; + macherr = bootstrap_look_up(bsport, KEXTD_SERVER_NAME, &kxport); + if (macherr) goto finish; + + // allocate a port to pass to kextd (in case we die) + macherr = mach_port_allocate(tport, MACH_PORT_RIGHT_RECEIVE, &myport); + if (macherr) goto finish; + + // loop trying to lock for reboot (i.e. no volumes are busy) + do { + nretries--; + macherr = kextmanager_lock_reboot(kxport, myport, busyDev, &busyStatus); + if (macherr) goto finish; + + if (busyStatus == EBUSY) { + if (*busyDev) { + warnx("%s is busy updating; delaying reboot (%d retries left)", + busyDev, nretries); + } else + warnx("kextd still starting up"); + if (nretries) sleep(LCK_DELAY); // don't sleep the last time + } + } while (busyStatus == EBUSY && nretries > 0); + + rval = busyStatus; + +finish: + if (macherr == BOOTSTRAP_UNKNOWN_SERVICE) { + mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); + rval = 0; + } else if (macherr) { + warnx("couldn't lock kext manager for reboot: %s", + mach_error_string(macherr)); + rval = ELAST + 1; + } + if (rval && myport != MACH_PORT_NULL) { + mach_port_mod_refs(tport, myport, MACH_PORT_RIGHT_RECEIVE, -1); + } + + return rval; +} +#endif + -- 2.45.2