]> git.saurik.com Git - apple/system_cmds.git/commitdiff
system_cmds-336.17.tar.gz mac-os-x-1048x86 v336.17
authorApple <opensource@apple.com>
Thu, 3 Aug 2006 20:36:17 +0000 (20:36 +0000)
committerApple <opensource@apple.com>
Thu, 3 Aug 2006 20:36:17 +0000 (20:36 +0000)
16 files changed:
at.tproj/Makefile.dist
atrun.tproj/Makefile.dist
atrun.tproj/atrun.8
getty.tproj/getty.8
getty.tproj/gettytab.5
getty.tproj/ttys.5
reboot.tproj/Makefile
reboot.tproj/Makefile.preamble
reboot.tproj/kextmanager.defs [new file with mode: 0644]
reboot.tproj/reboot.8
reboot.tproj/reboot.c
shutdown.tproj/Makefile
shutdown.tproj/Makefile.preamble
shutdown.tproj/kextmanager.defs [new file with mode: 0644]
shutdown.tproj/shutdown.8
shutdown.tproj/shutdown.c

index bdfa51536b78a3795555a24030c4880ed298f1fd..1468a6c005bfe13a327453e25718f27cf941fa07 100644 (file)
@@ -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
 
 PROG=  at
 SRCS=  at.c panic.c parsetime.c
index 726a2e79e4a34a83a0c1fe8349b06fde08457d7e..0980f04e542d48e0acb48b97235ba920415c4842 100644 (file)
@@ -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
 
 PROG=  atrun
 BINDIR=        /usr/libexec
index 7ebc04e191cdfc07e7b474e4e4443b22c10473c7..8d50f58c4d763fb4a8cf736b6dd429a9aa574343 100644 (file)
@@ -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.
 .\"
 .\" (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
 .\"
 .Dd December 5, 1993
 .Dt ATRUN 8
index cc6612fa64961d8d682c9027c085b939fab36f9a..a97f05331b3af45563c14f664c945345cb1c076e 100644 (file)
@@ -30,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     from: @(#)getty.8      8.1 (Berkeley) 6/4/93
 .\" 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
 .\"
 .Dd June 4, 1993
 .Dt GETTY 8
index 51d4cfede5b0397529e76d8906584aa0c641e059..38e9a96a6aa2f57f027adb428aeb3889fffcded9 100644 (file)
@@ -30,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     from: @(#)gettytab.5   8.4 (Berkeley) 4/19/94
 .\" 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
 .\"
 .Dd April 19, 1994
 .Dt GETTYTAB 5
index b2f6584f6ebb840e79efff033cfb15c36b4fd38b..3a2fc45bba6a055a26c86f55bbeb4feb0a088ceb 100644 (file)
@@ -30,7 +30,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"     from: @(#)ttys.5       8.1 (Berkeley) 6/4/93
 .\" 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
 .\"
 .Dd June 4, 1993
 .Dt TTYS 5
index 74f27bc90ba0e8c1761ce2c241169b1401c52237..804761c48337c8daedcaa51af620eb10ec9bac29 100644 (file)
@@ -13,10 +13,11 @@ PROJECTVERSION = 2.8
 PROJECT_TYPE = Tool
 
 CFILES = reboot.c
 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\
 
 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
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
index d5059b1a9606b91618e13146f4f3c48551b75880..618870c3a9413acd924f27020c1b0364efff6e2a 100644 (file)
@@ -1,2 +1,3 @@
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
 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 (file)
index 0000000..2a77d65
--- /dev/null
@@ -0,0 +1 @@
+#include <IOKit/kext/kextmanager_mig.defs>
index 0569b72cf3e1ec8c773cd7608520747b5bc3650d..46796be69f7a28a800a16918a4710a498d8f1347 100644 (file)
@@ -41,7 +41,7 @@
 .Nd stopping and restarting the system
 .Sh SYNOPSIS
 .Nm halt
 .Nd stopping and restarting the system
 .Sh SYNOPSIS
 .Nm halt
-.Op Fl lnq
+.Op Fl lnqu
 .Nm
 .Op Fl lnq
 .Sh DESCRIPTION
 .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.
 .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
 .El
 .Pp
 Normally, the
index 61b6e389d15b2b07d105bc063ef89c0f9fd9bd40..f970ca5252fec1e39aa6f074fee959cdb5f6ced2 100644 (file)
@@ -60,8 +60,19 @@ static const char rcsid[] =
 #include <string.h>
 #include <unistd.h>
 
 #include <string.h>
 #include <unistd.h>
 
+#ifdef __APPLE__
+#include "kextmanager.h"
+#include <IOKit/kext/kextmanager_types.h>
+#include <mach/mach_port.h>            // allocate
+#include <mach/mach.h>                 // task_self, etc
+#include <servers/bootstrap.h> // bootstrap
+#endif
+
 void usage(void);
 u_int get_pageins(void);
 void usage(void);
 u_int get_pageins(void);
+#ifdef __APPLE__
+int reserve_reboot(void);
+#endif
 
 int dohalt;
 
 
 int dohalt;
 
@@ -69,7 +80,7 @@ int
 main(int argc, char *argv[])
 {
        struct passwd *pw;
 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;
        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
 #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__
 #endif
                switch(ch) {
 #ifndef __APPLE__
@@ -109,6 +120,10 @@ main(int argc, char *argv[])
                        howto |= RB_POWEROFF;
                        break;
 #endif
                        howto |= RB_POWEROFF;
                        break;
 #endif
+               case 'u':
+                       uflag = 1;
+                       howto |= RB_UPSDELAY;
+                       break;
                case 'q':
                        qflag = 1;
                        break;
                case 'q':
                        qflag = 1;
                        break;
@@ -128,6 +143,13 @@ main(int argc, char *argv[])
                err(1, NULL);
        }
 
                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);
        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);
                            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);
                } 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 */
 
        reboot(howto);
        /* FALLTHROUGH */
 
+#ifndef __APPLE__
 restart:
 restart:
+#endif
        sverrno = errno;
        errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "",
            strerror(sverrno));
        sverrno = errno;
        errx(1, "%s%s", kill(1, SIGHUP) == -1 ? "(can't restart init): " : "",
            strerror(sverrno));
@@ -249,3 +274,67 @@ get_pageins()
        }
        return 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 = "<unknown>";
+
+       // 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
index a257e8ccc725876942f533c462ab651a274cabe3..e0df19de2d9f773a9cb928d8ecdebf2c84435d91 100644 (file)
@@ -15,9 +15,10 @@ PROJECT_TYPE = Tool
 HFILES = pathnames.h
 
 CFILES = shutdown.c
 HFILES = pathnames.h
 
 CFILES = shutdown.c
+DEFSFILES = kextmanager.defs
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble Makefile.dist\
-            shutdown.8
+            shutdown.8 $(DEFSFILES)
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
index d5059b1a9606b91618e13146f4f3c48551b75880..618870c3a9413acd924f27020c1b0364efff6e2a 100644 (file)
@@ -1,2 +1,3 @@
 OTHER_GENERATED_OFILES = $(VERS_OFILE)
 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 (file)
index 0000000..2a77d65
--- /dev/null
@@ -0,0 +1 @@
+#include <IOKit/kext/kextmanager_mig.defs>
index fb2c1f71fddfea0356440dceb523b9f3033f50a7..12bd570414cfd0f12fe2170d37b6a6f272aee5a3 100644 (file)
@@ -42,7 +42,9 @@
 .Nm
 .Op Fl
 .Oo
 .Nm
 .Op Fl
 .Oo
-.Fl h | 
+.Fl h 
+.Op Fl u
+|
 .Fl r | Fl k
 .Oc
 .Oo
 .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
 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,
 or
 .Fl r
 is specified,
@@ -98,6 +99,12 @@ option to
 or
 .Xr reboot 8 .
 This option should probably not be used.
 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
 .It Ar time
 .Ar Time
 is the time at which
index dcef480e4354e0aa2fb5796099c8c98d2f0e8b84..91ea293308225884e61e9d4c39eb35f3272c7a60 100644 (file)
@@ -65,6 +65,13 @@ static const char rcsid[] =
 #include <bsm/libbsm.h>
 #include <bsm/audit_uevents.h>
 
 #include <bsm/libbsm.h>
 #include <bsm/audit_uevents.h>
 
+#ifdef __APPLE__
+#include "kextmanager.h"
+#include <IOKit/kext/kextmanager_types.h>
+#include <mach/mach_port.h>            // allocate
+#include <mach/mach.h>                 // task_self, etc
+#include <servers/bootstrap.h> // bootstrap
+#endif
 
 #include "pathnames.h"
 
 
 #include "pathnames.h"
 
@@ -102,7 +109,7 @@ struct interval {
 #undef S
 
 static time_t offset, shuttime;
 #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;
 
 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);
 void timewarn(int);
 void usage(const char *);
 int audit_shutdown(int);
+#ifdef __APPLE__
+int reserve_reboot(void);
+#endif
 
 int
 main(argc, argv)
 
 int
 main(argc, argv)
@@ -139,7 +149,7 @@ main(argc, argv)
 #ifndef __APPLE__
        while ((ch = getopt(argc, argv, "-hknopr")) != -1)
 #else
 #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 '-':
 #endif
                switch (ch) {
                case '-':
@@ -150,6 +160,7 @@ main(argc, argv)
                        break;
                case 'k':
                        killflg = 1;
                        break;
                case 'k':
                        killflg = 1;
+                       oflag = 0;
                        break;
                case 'n':
                        nosync = "-n";
                        break;
                case 'n':
                        nosync = "-n";
@@ -162,6 +173,9 @@ main(argc, argv)
                        dopower = 1;
                        break;
 #endif
                        dopower = 1;
                        break;
 #endif
+        case 'u':
+            doups = 1;
+            break;
                case 'r':
                        doreboot = 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 (oflag && !(dohalt || doreboot))
                usage("-o requires -h or -r");
+               
+       if (doups && !dohalt)
+               usage("-u requires -h");
 #endif
 
        if (nosync != NULL && !oflag)
 #endif
 
        if (nosync != NULL && !oflag)
@@ -378,13 +395,18 @@ die_you_gravy_sucking_pig_dog()
 {
        char *empty_environ[] = { NULL };
 
 {
        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
 #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
 #ifndef __APPLE__
        (void)sleep(2);
 #endif
@@ -433,7 +455,13 @@ die_you_gravy_sucking_pig_dog()
                        warn(_PATH_REBOOT);
                }
                else if (dohalt) {
                        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);
                                (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,
        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);
 }
            " time [warning-message ...]\n");
        exit(1);
 }
@@ -638,3 +666,69 @@ int audit_shutdown(int exitstatus)
        }
        return 1;
 }
        }
        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 = "<unknown>";
+
+       // 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
+